确定类型是否为类类型?

Ben*_*ahi 8 c++ templates partial-specialization sfinae type-traits

在"C++模板 - 完整指南 - 第二版"一书的第19.8.4章中,作者展示了如何在编译时确定类型是否为类类型:

#include <iostream>
#include <type_traits>
using namespace std;

template <typename T, typename = void_t<>>
struct IsClass : false_type { };

template <typename T>
struct IsClass<T, void_t<int T::*>> : true_type { };

int main()
{
    struct S { };
    cout << IsClass<S>::value; // prints 1
}
Run Code Online (Sandbox Code Playgroud)

本段解释了部分特化如何检测类类型:

...只有类类型可以用作指向成员类型的基础.也就是说,在表单的类型构造中X Y::*,Y只能是类类型.以下公式IsClass<T>利用属性(并int任意选择类型X)

我不明白为什么选择int作为X工作,即使我们测试IsClass<>一个S完全没有成员的结构(它也适用于具有其他成员的类类型int)

rus*_*tyx 9

简而言之,这是因为标准是这样说的.

根据[dcl.mptr]/2(我这里仅包括相关部分):

[ 例如:

struct X {
  int a;
};
struct Y;

double X::* pmd;
char Y::* pmc;
Run Code Online (Sandbox Code Playgroud)

...即使没有类型的成员,
声明pmd也是格式良好的.同样,即使是不完整的类型,声明也是格式良好的. ...XdoublepmcY

基本上,只要S知道类型是类类型,构造S::*就是格式良好的.

所以你甚至可以这样:

int main()
{
    struct S;
    cout << IsClass<S>::value; // still prints 1
}
Run Code Online (Sandbox Code Playgroud)