IsClassT<T>中为什么要用"int C::*"?我对 int 类型感到困惑
In IsClassT<T>, why use "int C::*"? I am confusing about the int type
书 C++ 模板完整指南 中描述的示例:
template <typename T>
class IsClass {
private:
typedef char One;
typedef struct { char a[2];} Two;
template<typename C> static One test(int C::*);
template<typename C> static Two test(...);
public:
enum {
Yes = (sizeof(IsClass<T>::test<T>(0)) == 1)
};
enum {
No = !Yes
};
};
我已阅读相关主题Where can I find a description about the usage of "int C::*"?
我的概念是 C::* 表示指向成员的指针,而 test(0) 表示 test(nullptr),但我还有其他问题:
- 假设编译器不检查 class C 是否真的有 int 类型的成员。为什么编译器不检查?
- int 类型 int C::* 可以替换为任何类型,但 void,尽管我认为 void 不那么令人困惑。为什么报这个错误?
In file included from testisclass.cpp:12:
../inc/isclass.hpp:17:54: error: cannot declare pointer to ‘void’ member
17 | template<typename C> static One test(void C::*);
| ^
../inc/isclass.hpp: In instantiation of ‘class IsClass<A>’:
testisclass.cpp:22:16: required from here
../inc/isclass.hpp:17:41: error: creating pointer to member of type void
17 | template<typename C> static One test(void C::*);
| ^~~~
../inc/isclass.hpp: In instantiation of ‘class IsClass<int>’:
testisclass.cpp:28:18: required from here
../inc/isclass.hpp:17:41: error: creating pointer to member of type void
- 是=true/false定义完整,为什么还是没有定义?
因为标准是这么说的。在 [dcl.mptr]:
3 - Example: [...]
double X::* pmd;
[...] The declaration of pmd
is well-formed even though X
has no members of type double
. [...]
4 - A pointer to member shall not point to [...] “cv
void
”.
一些可能的原因:如果你必须检查数据成员,你将无法定义指向不完整数据成员的指针类。虽然 void*
对于与 C 的互操作性和类型擦除很有用,但 C 没有指向成员类型的指针,而且您不太可能需要类型擦除指向成员的指针。
至于为什么在 Yes
之外还定义了 No
- 不知道,也许作者认为它可能有用。
书 C++ 模板完整指南 中描述的示例:
template <typename T>
class IsClass {
private:
typedef char One;
typedef struct { char a[2];} Two;
template<typename C> static One test(int C::*);
template<typename C> static Two test(...);
public:
enum {
Yes = (sizeof(IsClass<T>::test<T>(0)) == 1)
};
enum {
No = !Yes
};
};
我已阅读相关主题Where can I find a description about the usage of "int C::*"? 我的概念是 C::* 表示指向成员的指针,而 test(0) 表示 test(nullptr),但我还有其他问题:
- 假设编译器不检查 class C 是否真的有 int 类型的成员。为什么编译器不检查?
- int 类型 int C::* 可以替换为任何类型,但 void,尽管我认为 void 不那么令人困惑。为什么报这个错误?
In file included from testisclass.cpp:12:
../inc/isclass.hpp:17:54: error: cannot declare pointer to ‘void’ member
17 | template<typename C> static One test(void C::*);
| ^
../inc/isclass.hpp: In instantiation of ‘class IsClass<A>’:
testisclass.cpp:22:16: required from here
../inc/isclass.hpp:17:41: error: creating pointer to member of type void
17 | template<typename C> static One test(void C::*);
| ^~~~
../inc/isclass.hpp: In instantiation of ‘class IsClass<int>’:
testisclass.cpp:28:18: required from here
../inc/isclass.hpp:17:41: error: creating pointer to member of type void
- 是=true/false定义完整,为什么还是没有定义?
因为标准是这么说的。在 [dcl.mptr]:
3 - Example: [...]
double X::* pmd;
[...] The declaration ofpmd
is well-formed even thoughX
has no members of typedouble
. [...]4 - A pointer to member shall not point to [...] “
cv
void
”.
一些可能的原因:如果你必须检查数据成员,你将无法定义指向不完整数据成员的指针类。虽然 void*
对于与 C 的互操作性和类型擦除很有用,但 C 没有指向成员类型的指针,而且您不太可能需要类型擦除指向成员的指针。
至于为什么在 Yes
之外还定义了 No
- 不知道,也许作者认为它可能有用。