[英]Pointer-to-member confusion
I'm trying to understand the consistency in the error that is thrown in this program: 我试图了解此程序中引发的错误的一致性:
#include <iostream>
class A{
public:
void test();
int x = 10;
};
void A::test(){
std::cout << x << std::endl; //(1)
std::cout << A::x << std::endl; //(2)
int* p = &x;
//int* q = &A::x; //error: cannot convert 'int A::*' to 'int*' in initialization| //(3)
}
int main(){
const int A::* a = &A::x; //(4)
A b;
b.test();
}
The output is 10 10
. 输出为
10 10
。 I labelled 4 points of the program, but (3) is my biggest concern: 我给程序标记了4分,但是(3)是我最大的担忧:
x
is fetched normally from inside a member function. x
通常是从成员函数内部获取的。 x
of the object is fetched using the scope operator and an lvalue to the object x
is returned. x
的对象是取出使用范围运算符和一个左值到对象x
被返回。 A::x
returned an int
lvalue in (2), why then does &A::x
return not int*
but instead returns int A::*
? A::x
在(2)中返回一个int
左值,为什么&A::x
不返回int*
而是返回int A::*
? The scope operator even takes precedence before the &
operator so A::x
should be run first, returning an int
lvalue, before the address is taken. &
运算符,因此应在获取地址之前先运行A::x
,并返回一个int
左值。 ie this should be the same as &(A::x)
surely? &(A::x)
相同吗? (Adding parentheses does actually work by the way). So why exactly does A::x
not return the address of the object x
but instead returns the address of the member, ignoring precedence of ::
before &
? 那么,为什么
A::x
不返回对象x
的地址,而是返回成员的地址,而忽略::
在&
之前的优先级呢?
Basically, it's just that the syntax &A::x
(without variation) has been chosen to mean pointer-to-member. 基本上,只是选择
&A::x
语法(无变化)来表示成员指针。
If you write, for example, &(A::x)
, you will get the plain pointer you expect. 例如,如果编写
&(A::x)
,则将获得所需的普通指针。
More information on pointers-to-members, including a note about this very property, can be found here . 在此处可以找到有关指向成员的指针的更多信息,包括有关此属性的注释。
The C++ standard doesn't explicitly specify operator precedence; C ++标准未明确指定运算符优先级; it's possible to deduce operator precedence implicitly from the grammar rules, but this approach fails to appreciate the occasional special case like this which doesn't fit into a traditional model of operator precedence.
可以从语法规则中隐式推断出运算符优先级,但是这种方法无法理解像这样的特殊情况,这种特殊情况不适用于传统的运算符优先级模型。
[expr.unary.op]/3: [expr.unary.op] / 3:
The result of the unary
&
operator is a pointer to its operand.一元
&
运算符的结果是指向其操作数的指针。 The operand shall be an lvalue or a qualified-id .操作数应为左值或qualified-id 。 If the operand is a qualified-id naming a non-static or variant member
m
of some classC
with typeT
, the result has type 'pointer to member of classC
of typeT
' and is a prvalue designatingC::m
.如果操作数是一个合格的id ,它使用类型
T
命名某些C
类的非静态或变体成员m
,则结果的类型为“指向类型T
的C
类成员的指针”,并且是一个指定C::m
的prvalue。 Otherwise, if the type of the expression isT
, the result has type 'pointer toT
' and is a prvalue that is the address of the designated object or a pointer to the designated function.否则,如果表达式的类型为
T
,则结果的类型为“指向T
的指针”,并且是prvalue,它是指定对象的地址或指向指定函数的指针。
/4: / 4:
A pointer to member is only formed when an explicit
&
is used and its operand is a qualified-id not enclosed in parentheses.仅当使用显式
&
且其操作数是未括在括号中的限定ID时,才会形成指向成员的指针。 [ Note: that is, the expression&(qualified-id)
, where the qualified-id is enclosed in parentheses, does not form an expression of type 'pointer to member'.[ 注意:即,表达式
&(qualified-id)
不能将类型为pointer to member的表达式形成为表达式,其中qualified-id用括号括起来。
[expr.prim.general]/9: [expr.prim.general] / 9:
A nested-name-specifier that denotes a class, optionally followed by the keyword
template
, and then followed by the name of a member of either that class or one of its base classes, is a qualified-id .表示一个类的nested-name-specifier是一个qualified-id ,该类后面可以是关键字
template
,然后是该类或其基类之一的成员的名称。
What it all adds up to is that an expression of the form &A::x
has the type "pointer to member x
of class A
" if x
is a non-static member of a non-union class A
, and operator precedence has no influence on this. 如果
x
是非联盟类A
的非静态成员,并且运算符优先级没有,则&A::x
形式的表达式的类型总和是“指向类A
成员x
的指针”。影响。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.