我在哪里可以找到关于"int C ::*"用法的描述?

Hua*_*Lei 8 c++ stl

在一段代码中,我发现了一些东西:

template<typename T>
class IsClassT {
  private:
    typedef char One;
    template<typename C> static One test(int C::*);
...
Run Code Online (Sandbox Code Playgroud)

问题是我在哪里可以找到关于为什么"int C ::*"的使用在函数test()定义中有效的描述?

CB *_*ley 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 );
}
Run Code Online (Sandbox Code Playgroud)


Ale*_* C. 6

我不会描述是什么int C::*意思,因为@Charles Bailey已经做得非常好.不过我会回答你的问题:

(...)为什么"int C ::*"的使用在函数test()定义中有效?

关键点是,当且仅当是类类型时,int C::*(指向类型成员的指针int)的使用是有效的.否则该类型是不正确的. Cint C::*

这就是你的原因

template<typename C> static One test(int C::*);
Run Code Online (Sandbox Code Playgroud)

而且很可能在下面的某个地方

template <typename> static Two test(...);
static const bool value = sizeof(test<T>(0)) == 1;
Run Code Online (Sandbox Code Playgroud)

test<T>(0)编译器看到它时,它会检查候选者test.它找到两个:

template<typename C> static One test(int C::*);   
template <typename> static Two test(...);
Run Code Online (Sandbox Code Playgroud)

第一个优先于第二个,因为1)它们都是模板函数,2)最后查找省略号.如果第一个形成不良(即,当且仅当 C不是类类型)时,则简单地丢弃它并且进行第二次重载.此行为的昵称为SFINAE(替换失败不是错误).

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