判断一个类型是否是class类型?
Determining whether a type is a class type?
在 "C++ Templates - The Complete Guide - Second Edition" 一书的第 19.8.4 章中,作者展示了如何在编译时确定类型是否为 class 类型:
#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
}
本段说明偏特化如何检测 class 类型:
... only class types can be used as the basis of pointer-to-member types. That is, in a type construct of the form X Y::*
, Y
can only be a class type. The following formulation of IsClass<T>
exploits the property (and picks int
arbitrarily for type X
)
我不明白的是为什么选择 int
作为 X
有效,即使我们使用根本没有成员的结构 S
测试 IsClass<>
(它也适用于具有 int
以外成员的 class 类型)
What I don't understand is why picking int
as X
works, even if we test IsClass<> with a struct S that has no members at all (It also works for class types having a member other than int)
它不必是 int
,因为它只是扮演 占位符 的角色。
您可以将其替换为 double
或 char
并看到相同的结果。
给定的 class 类型 T
是否有成员函数根本不重要,因为 IsClass
试图看到的只是那个表达式:
X Y::*
格式正确。
这就像您不需要实际的函数定义(非成员函数)只是为了声明指向该函数的指针类型,如下所示:
int main()
{
// It doesn't matter whether there's a function int (*)(int, int, int) indeed because it's just merely a declaration
using FuncP = int (*)(int, int, int);
FuncP P;
}
简而言之,因为标准是这么说的。
根据 [dcl.mptr]/2(我在此处仅包含相关部分):
[ Example:
struct X {
int a;
};
struct Y;
double X::* pmd;
char Y::* pmc;
. . .
The declaration of pmd
is well-formed even though X
has no members of type double
. Similarly, the declaration of pmc
is well-formed even though Y
is an incomplete type.
. . .
基本上,只要类型 S
已知是 class 类型,构造 S::*
就是合式的。
所以你甚至可以拥有这个:
int main()
{
struct S;
cout << IsClass<S>::value; // still prints 1
}
在 "C++ Templates - The Complete Guide - Second Edition" 一书的第 19.8.4 章中,作者展示了如何在编译时确定类型是否为 class 类型:
#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
}
本段说明偏特化如何检测 class 类型:
... only class types can be used as the basis of pointer-to-member types. That is, in a type construct of the form
X Y::*
,Y
can only be a class type. The following formulation ofIsClass<T>
exploits the property (and picksint
arbitrarily for typeX
)
我不明白的是为什么选择 int
作为 X
有效,即使我们使用根本没有成员的结构 S
测试 IsClass<>
(它也适用于具有 int
以外成员的 class 类型)
What I don't understand is why picking
int
asX
works, even if we test IsClass<> with a struct S that has no members at all (It also works for class types having a member other than int)
它不必是 int
,因为它只是扮演 占位符 的角色。
您可以将其替换为 double
或 char
并看到相同的结果。
给定的 class 类型 T
是否有成员函数根本不重要,因为 IsClass
试图看到的只是那个表达式:
X Y::*
格式正确。
这就像您不需要实际的函数定义(非成员函数)只是为了声明指向该函数的指针类型,如下所示:
int main()
{
// It doesn't matter whether there's a function int (*)(int, int, int) indeed because it's just merely a declaration
using FuncP = int (*)(int, int, int);
FuncP P;
}
简而言之,因为标准是这么说的。
根据 [dcl.mptr]/2(我在此处仅包含相关部分):
[ Example:
struct X { int a; }; struct Y; double X::* pmd; char Y::* pmc;
. . .
The declaration ofpmd
is well-formed even thoughX
has no members of typedouble
. Similarly, the declaration ofpmc
is well-formed even thoughY
is an incomplete type.
. . .
基本上,只要类型 S
已知是 class 类型,构造 S::*
就是合式的。
所以你甚至可以拥有这个:
int main()
{
struct S;
cout << IsClass<S>::value; // still prints 1
}