在一段代码中,我找到了一些东西:
template<typename T>
class IsClassT {
private:
typedef char One;
template<typename C> static One test(int C::*);
...
问题是我在哪里可以找到关于为什么“int C :: *”的使用在函数test()定义中有效的描述?
答案 0 :(得分:10)
int C::*
是指向C
类型int
成员的指针。搜索“指向成员的指针”。处理此声明语法的标准部分(ISO / IEC 14882:2003)是8.3.3指向成员的指针[dcl.mptr]。
使用示例。
struct Example
{
int a;
int b;
};
int test( Example& ex, int Example::* p )
{
return ex.*p;
}
int main()
{
Example x = { 3, 5 };
// Convoluted way of extracting x.a and x.b
int a = test( x, &Example::a );
int b = test( x, &Example::b );
}
答案 1 :(得分:6)
我不会描述int C::*
的含义,因为@Charles Bailey已经做得很好。不过我会回答你的问题:
(...)为什么“int C :: *”的用法在函数test()中有效 定义
关键点是int C::*
(指向int
类型成员的指针)的使用是有效的当且仅当 C
是类类型时。否则,int C::*
类型格式不正确。
这就是你
的原因template<typename C> static One test(int C::*);
并且很可能在某处
template <typename> static Two test(...);
static const bool value = sizeof(test<T>(0)) == 1;
当编译器看到test<T>(0)
时,它会检查test
的候选者。它找到两个:
template<typename C> static One test(int C::*);
template <typename> static Two test(...);
第一个优先于第二个,因为1)它们都是模板函数,2)最后查找省略号。如果第一个形成不良(即当且仅当 C
不是类类型),那么它只是被丢弃而第二个重载是拍摄。此行为的昵称为 SFINAE (替换失败不是错误)。
测试返回类型的大小(记住sizeof(char)
始终为1),您可以在编译时评估test
采取的内容,即。 T
是否为班级类型。
答案 2 :(得分:2)
这是指向成员的指针 一个简单的例子来理解成员指针。
class A
{
int a;
int b;
void DoSomething();
};
int main()
{
A *ObjPtr;
//pointer to member a
int A::*ptr = &A::a;
//Usage
objPtr->*ptr = NULL;
//pointer to member function
void (A::*FuncPtr)(void) = &A::DoSomething;
//Usage
(objPtr->*FuncPtr)(void);
return 0;
}