为什么这个 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_tdecltype(typeid(typename T::key_type), void())简化为std::void_t<typename T::key_type>