I'm trying to figure out why SFINAE doesn't work with a direct template argument initialization?
It works in this form, when I declare another template parameter, here:
#include <iostream>
template <bool B, class T = void>
class enable_if {};
template <class T>
struct enable_if<true, T> { typedef T type; };
template <bool B, class T>
using enable_if_t = typename enable_if<B,T>::type;
template< typename T >
struct Y {
public:
template< typename U = T >
enable_if_t<true, U>
foo() {
return 111;
}
template< typename U = T >
enable_if_t<false, U>
foo() {
return 222;
}
};
int main() {
Y< double > y;
std::cout << y.foo() << std::endl;
}
(prints out 111)
but if I refactor to this syntax, the compiler gives an error:
#include <iostream>
template <bool B, class T = void>
class enable_if {};
template <class T>
struct enable_if<true, T> {
typedef T type;
};
template <bool B, class T>
using enable_if_t = typename enable_if<B,T>::type;
template< typename T >
struct Y {
template< typename U = enable_if_t<true, T> >
U
foo() {
return 11;
}
template< typename U = enable_if_t<false, T> >
U
foo() {
return 12;
}
};
int main() {
Y< double > y;
std::cout << y.foo() << std::endl;
}
"Class member cannot be redeclared" I assume the second instance formed invalid and should be excluded by SFINAE?
And why can't I declare foo()'s like this:
enable_if_t<true, T> foo() { return 11; }
enable_if_t<false, T> foo() { return 12; }
based just on the class template's T parameter? the second enable_if_t should not be valid and the instance of foo() should be discarded, right?
答案 0 :(得分:1)
In the second case, you declare two class methods:
template<typename U> U foo();
You can't have two template class methods with the same signature and name just like you can't declare two non-template class methods with the same signature and name:
int bar();
and
int bar();
Your two template class methods have different template parameters defaults, but that is immaterial. Template parameter defaults are not considered to be a part of the signature. SFINAE does not come into play here. SFINAE is something that happens when template substitution occurs, the "S" part, not declaration.