I have got an untypical requirement. I'm writing a setup library function, which should be called with only constant values and class names. I made something like this:
template <unsigned index, class layerClass, typename...Args>
void setup_layers() {
//add layer
//recursively call yourself
setup_layers<Args...>();
}
template <unsigned index, class layerClass>
void setup_layers() {
//add layer
}
When I try use my function:
struct MyLayer {};
int main (int argc, char **argv)
{
constexpr unsigned LAYER_NUM = 0;
setup_layers<LAYER_NUM, MyLayer>();
return 0;
}
the compiler reports the error call of overloaded ‘setup_layers<LAYER_NUM, MyLayer>()’ is ambiguous
I'm not sure how can I accomplish my requirement in the other way :(. If I could pass class names as parameters to my function via normal arguments it would be fine, but C++ has no such feature...
EDIT OK, it seems my "solution" goes nowhere and simply doesn't work. Because I don't want to delete a question with answers, then maybe I should ask my question differently:
I want users of my library to set a list of layers with indexes (where numbers in those indexes doesn't have to have consecutive numbers). The reason why I wanted to do it using templates is because templates can allow only constant values as parameters. To put it simply: I want to forbid my users from using variables as parameters for indexes.
Here's one option to resolve the ambiguity: You could rename the function doing the actual setup implementation. I've called it setup_impl
:
template <unsigned index, class layerClass>
void setup_impl() {
//add layer
std::cout << index << '\n';
}
template <unsigned index, class layerClass, class... Args>
void setup_layers() {
setup_impl<index, layerClass>();
if constexpr (sizeof...(Args) > 0) {
setup_layers<index + 1, Args...>();
}
}
If index
is supposed to be the same every time a Layer class is used, you could make the index
a property of the Layer classes.
Example:
template <class layerClass>
void setup_impl() {
std::cout << layerClass::index << '\n';
}
template <class... Args>
void setup_layers() {
(setup_impl<Args>(), ...); // fold expression
}
struct MyLayer1 { static constexpr unsigned index = 11; };
struct MyLayer2 { static constexpr unsigned index = 22; };
struct MyLayer3 { static constexpr unsigned index = 33; };