struct X {
int f(int);
static int f(long);
};
int (X::*p1)(int) = &X::f; // OK
int (*p2)(int) = &X::f; // error: mismatch
int (*p3)(long) = &X::f; // OK
int (X::*p4)(long) = &X::f; // error: mismatch
int (X::*p5)(int) = &(X::f); // error: wrong syntax for pointer to member
int (*p6)(long) = &(X::f); // OK
我认为p1和p5是相同的情况。为什么p5错了?
答案 0 :(得分:5)
因为标准是这样说的。来自N3936:
5.3.1一元运算符
- 指向成员的指针仅在显式&使用,其操作数是一个未括在括号中的限定ID 。 [ 注意: 也就是表达式&(qualified-id),其中qualified-id是 括在括号中,不形成“指针”类型的表达式 成员。“也没有qual-id,因为没有隐含的 从非静态成员函数的qualified-id转换为 键入“指向成员函数的指针”,因为它来自左值 函数类型为“指向函数的指针”(4.3)。也不是 & unqualified-id指向成员的指针,即使在范围内也是如此 unqualified-id的类。 - 尾注]
醇>
答案 1 :(得分:2)
C ++标准的内置operator &
定义指出,只有当&
的参数是 qualified-id 时才会出现{ {1}},Class::Member
会导致指向成员的指针。括号使其不再是 qualified-id ,因此它会尝试直接解析&
,这在此上下文中是非法的:您正在为X::f
分配int (*)(long)
int (X::*)(int)
。
两种情况之间的区别解决了歧义。让我们说你有:
struct X {
int m;
};
struct Y {
int m;
};
struct Z : X, Y {
void F();
};
void Z::F() {
int X::*p1 = &X::m;
int *p2 = &(X::m);
}
此处,&X::m
是指向成员的指针,而&(X::m)
是指向int
的普通指针,使用X::
限定来解决X
之间的歧义1}}' m
和Y
' s m
。