For the first option (dot) the first expression shall be a glvalue having complete class type. For the second option (arrow) the first expression shall be a prvalue having pointer to complete class type. The expression E1->E2 is converted to the equivalent form (*(E1)).E2; the remainder of [expr.ref] will address only the first option (dot).68 In either case, the id-expression shall name a member of the class or of one of its base classes. [ Note: Because the name of a class is inserted in its class scope (Clause [class]), the name of a class is also considered a nested member of that class. — end note ] [ Note: [basic.lookup.classref] describes how names are looked up after the . and -> operators. — end note ]
根据本段,左值到右值的转换应用于以下代码段中的 p
。但它不适用于a
。为什么标准规定第一个选项(点)为左值,第二个选项(箭头)为右值?
struct A{ void f() {} };
A a;
A* p = new A;
int main() {
a.f();
p->f();
}
最佳答案
请记住,prvalues 可以通过临时物化转换 [conv.rval] 转换为 xvalues:
A prvalue of type
T
can be converted to an xvalue of typeT
. This conversion initializes a temporary object (15.2) of typeT
from the prvalue by evaluating the prvalue with the temporary object as its result object, and produces an xvalue denoting the temporary object.T
shall be a complete type. [Note: IfT
is a class type (or array thereof), it must have an accessible and non-deleted destructor; see 15.4. — end note] [Example:struct X { int n; }; int k = X().n; // OK, X() prvalue is converted to xvalue
— end example]
在引入这种新的纯右值到左值转换之前,C++14 没有限制后缀表达式是左值。
关于这一点,C++11 是第一个通过(当时的)新右值引用类型实现用户可定义的、不受约束的右值到左值转换的修订版:auto&& x = f() ;
使纯右值 f()
变成一个 xvalue x
。
关于c++ - [expr.ref]/2 中的左值到右值转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43016421/