C++ 我在哪里可以找到有关“的用法”的说明;INTC::*“;?

C++ 我在哪里可以找到有关“的用法”的说明;INTC::*“;?,c++,stl,C++,Stl,在一段代码中,我发现如下内容: template<typename T> class IsClassT { private: typedef char One; template<typename C> static One test(int C::*); ... 模板 类是类{ 私人: 类型1; 模板静态一次测试(int C::*); ... 问题是,我在哪里可以找到关于为什么“int C:*”的用法在函数测试()定义中有效的描述?int C:*

在一段代码中,我发现如下内容:

template<typename T>
class IsClassT {
  private:
    typedef char One;
    template<typename C> static One test(int C::*);
...
模板
类是类{
私人:
类型1;
模板静态一次测试(int C::*);
...

问题是,我在哪里可以找到关于为什么“int C:*”的用法在函数测试()定义中有效的描述?

int C:*
是指向
int
类型的
C
成员的指针。搜索“指向成员的指针”。标准部分(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 );
}

它是指向成员的指针。
一个简单的例子来理解指向成员的指针

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;
}

我不会描述
int C:::*
的意思,因为@Charles Bailey已经做得很好了。不过我会回答你的问题:

(…)为什么在函数测试()中使用“int C::*”是有效的 定义

关键的一点是
int C:::*
(指向
int
类型的成员的指针)的用法在当且仅当
C
是类类型时才有效。否则,类型
int C::*
格式错误

这就是为什么你

template<typename C> static One test(int C::*);
第一个函数优先于第二个函数,因为1)它们都是模板函数,2)省略号是最后一个查找的。如果第一个函数格式不正确(即,如果且仅当
C
不是类类型),那么它将被简单地丢弃,并使用第二个重载。这种行为被称为SFINAE(因为替换失败不是错误)


测试返回类型的大小(请记住
sizeof(char)
始终为1),您可以在编译时评估所进行的
test
,即
T
是否为类类型。

如果是这样的话,我的错。它与刚才的int*有什么不同?Nvm,明白了。@Grozz:
int*
可以是int(s)的任何引用一般来说,
int C::*
是对必须是
C类
@Sujoy成员的int的引用,我想说“
int C:*
是指向类型为
int
C类
成员的指针。”。它更精确。@Sujoy:I指向成员的指针本身并不是对
int
的受限引用,因为它不绑定到单个
int
对象。它是一个实体,允许您从特定类的任何实例访问特定成员。它更像是一个偏移量,而不是指针。@charles:是的。我正在尝试g表示虽然
int*
可以指向任何
int',
int C::*`不能。如果我错了,请纠正我。我正在阅读“C++模板”,对这段代码感到困惑,你的回答正好解决了我的困惑:o) Thanks@Huang:这是一种经典技术。你可以阅读或通过谷歌搜索SFINAE来了解更多关于此类编译时程序的信息。Stackoverflow也充满了SFINAE的技巧。
template <typename> static Two test(...);
static const bool value = sizeof(test<T>(0)) == 1;
template<typename C> static One test(int C::*);   
template <typename> static Two test(...);