Today I write the code below with a mistake:
template<int V>
typename std::enable_if<(V > 0)>::type
Test() {
Test<V - 1>();
}
template<int V>
typename std::enable_if<(V == 0)>::type
Test() {
std::cout << "0" << std::endl;
}
int main() {
Test<1>();
}
The compiler errored my that no matching function for call to ‘Test<(1 - 1)>()’, I checked and found that I should put the std::enable_if<(V == 0)>::type version first, or , I use forward declaration like this:
// forward declaration
template<int V>
typename std::enable_if<(V == 0)>::type
Test();
template<int V>
typename std::enable_if<(V > 0)>::type
Test() {
Test<V - 1>();
}
template<int V>
typename std::enable_if<(V == 0)>::type
Test() {
std::cout << "0" << std::endl;
}
int main() {
Test<1>();
}
The I noticed that when I write code using partial specialization, I never met this problem before, for example:
template <int V, typename = void>
struct Foo {
static void Test() {
std::cout << V << std::endl;
Foo<V - 1>::Test();
}
};
template <int V>
struct Foo <V, typename std::enable_if<V == 0>::type> {
static void Test() {
std::cout << "0" << std::endl;
}
};
int main() {
Foo<1>::Test();
}
this code works find and I didn't use forward declaration, so here's my question:
Why the function version cannot "see" functions declarations after itself, while the struct version knows? Did SFINAE happened in the function version's compilation?
P.S. Here's the error message using clang, which seems more specific:
/home/liu/source/untitled4/main.cpp:7:3: error: call to function 'Test' that is neither visible in the template definition nor found by argument-dependent lookup
Test<V - 1>();
And here's the error message I mentioned in my question using GCC:
/home/liu/source/untitled4/main.cpp:7:14: error: no matching function for call to ‘Test<(1 - 1)>()’
Test<V - 1>();
And I don't have a Windows environment on my hand for now, I'll paste the error later if MSVC reports errors.