I'm unable to figure out why this happens. The question and comments are inline.
using DefaultType_t = void;
template<typename...>
using void_t = DefaultType_t;
template<typename T>
struct is_float;
template<>
struct is_float<float> {
using type = float;
};
template<typename T>
using is_float_t = typename is_float<T>::type;
template<typename , typename = DefaultType_t>
struct A {
A() {std::printf("\nCalled 0\n");}
};
template<class T>
struct A<T, void_t<is_float_t<T>>> {
A() {std::printf("\nCalled 1\n");}
};
int main() {
is_float_t<float> {}; // Works fine ------\\
// ==> I understand these two cases.
is_float_t<int> {}; // Compile Error ---//
A<int> {}; // Prints Called 1 <Q> Why does this not Print Called 0 ??
// Because is_float_t<int> is erroneous,
// so shouldn't SFINAE apply ?
}
So the in-lined question once again : Why does A<int> {};
not print Called 0
? A<AnyType>
would first pick up the default template parameter from the base template which happens to be DefaultType_t
in this case. Then it would try to find if there is more specialized version of it. According to me there is none because the specialized one has the second template parameter ill-formed because is_float_t<int>
is ill-formed. So it should just pick the base. No?
using GCC/G++ 4.8.2
on Ubuntu 14.04 {64 bits}
with -std=c++11