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)
简而言之,这是因为标准是这样说的.
根据[dcl.mptr]/2(我这里仅包括相关部分):
[ 例如:
Run Code Online (Sandbox Code Playgroud)struct X { int a; }; struct Y; double X::* pmd; char Y::* pmc;...即使没有类型的成员,
声明pmd也是格式良好的.同样,即使是不完整的类型,声明也是格式良好的. ...XdoublepmcY
基本上,只要S知道类型是类类型,构造S::*就是格式良好的.
所以你甚至可以这样:
int main()
{
struct S;
cout << IsClass<S>::value; // still prints 1
}
Run Code Online (Sandbox Code Playgroud)