为什么这个 sfinae 不起作用?
Why does this of sfinae not work?
#include <type_traits>
using namespace std;
struct A
{
using key_type = int;
};
template<typename T, typename = void>
struct has_key_type : false_type
{};
template<typename T>
struct has_key_type<T, decltype(typeid(typename T::key_type), void())>: true_type
{};
int main()
{
cout << has_key_type<A>::value << endl;
cout << has_key_type<int>::value << endl;
}
输出为:
1
0
符合预期。但是,如果我从
decltype(typeid(typename T::key_type), void())
到
decltype(typeid(typename T::key_type), int())
如下:
template<typename T>
struct has_key_type<T, decltype(typeid(typename T::key_type), int())>: true_type
{};
输出为:
0
0
为什么第二个版本不行?
您没有提供第二个模板参数,因此它将使用默认模板参数,即 void
。在你的第二个版本中,decltype(typeid(typename T::key_type), int())
的类型是int
,所以has_key_type<A>
,等价于has_key_type<A, void>
,肯定不会匹配这个偏特化。
顺便说一句,从C++17开始,你可以使用std::void_t
将decltype(typeid(typename T::key_type), void())
简化为std::void_t<typename T::key_type>
。
#include <type_traits>
using namespace std;
struct A
{
using key_type = int;
};
template<typename T, typename = void>
struct has_key_type : false_type
{};
template<typename T>
struct has_key_type<T, decltype(typeid(typename T::key_type), void())>: true_type
{};
int main()
{
cout << has_key_type<A>::value << endl;
cout << has_key_type<int>::value << endl;
}
输出为:
1
0
符合预期。但是,如果我从
decltype(typeid(typename T::key_type), void())
到
decltype(typeid(typename T::key_type), int())
如下:
template<typename T>
struct has_key_type<T, decltype(typeid(typename T::key_type), int())>: true_type
{};
输出为:
0
0
为什么第二个版本不行?
您没有提供第二个模板参数,因此它将使用默认模板参数,即 void
。在你的第二个版本中,decltype(typeid(typename T::key_type), int())
的类型是int
,所以has_key_type<A>
,等价于has_key_type<A, void>
,肯定不会匹配这个偏特化。
顺便说一句,从C++17开始,你可以使用std::void_t
将decltype(typeid(typename T::key_type), void())
简化为std::void_t<typename T::key_type>
。