我无法弄清楚为什么会发生这种情况。问题和评论是内联的。
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 ?
}
所以再次插入问题:为什么不A<int> {};
打印Called 0
?A<AnyType>
将首先从恰好DefaultType_t
在这种情况下的基本模板中获取默认模板参数。然后它会尝试查找是否有更专业的版本。根据我的说法,没有,因为专门的模板参数的第二个模板参数格式错误,因为is_float_t<int>
格式错误。所以它应该只选择基地。不?
使用GCC/G++ 4.8.2
_ Ubuntu 14.04 {64 bits}
_-std=c++11