I'm using enable_if
class member functions to iterate over a variational template argument. Here is a minimal example (without the actual variadic)
#include <iostream>
template<int size> class Test {
public:
template<int i = 0> typename std::enable_if<i == size, void>::type test() {}
template<int i = 0> typename std::enable_if<i < size, void>::type test() {
std::cout << "cycle: " << i << '\n';
test<i + 1>();
}
};
int main(int, char**) {
Test<10> a;
a.test<>();
}
It works just fine but now I'm having problems with dependencies and decided to separate the declarations and definitions. I tried this:
#include <iostream>
template<int size> class Test {
public:
template<int i = 0> void test();
};
template<int size>
template<int i> typename std::enable_if<i == size, void>::type Test<size>::test() {}
template<int size>
template<int i> typename std::enable_if<(i < size), void>::type Test<size>::test() {
std::cout << "cycle: " << i << '\n';
test<i + 1>();
}
int main(int, char**) {
Test<10> a;
a.test<>();
}
but GCC says that error: out-of-line definition of 'test' does not match any declaration in 'Test<size>'
. I managed to make it work by including definitions for both cases of test
. My question is: why doesn't this work? Shouldn't the compiler only find one of the declarations for any i
? Thank you in advance for any help!
template<int i = 0>
typename std::enable_if<i == size, void>::type test() { }
template<int i = 0>
typename std::enable_if<i < size, void>::type test() { /* ... */ }
The two member functions above are completely different, they just happen to have the same name test
. They have different signatures and must be declared separately. It's similar to writing:
template<int i = 0>
int test() { }
template<int i = 0>
float test() { /* ... */ }
Would you expect to be able to have a single declaration for both of those in your class definition?