[expr.ref]/2 中的左值到右值转换
Lvalue-to-rvalue conversion in [expr.ref]/2
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 可以通过临时物化转换转换为 xvalues [conv.rval]:
A prvalue of type T
can be converted to an xvalue of type T
. This conversion initializes a temporary object (15.2) of type T
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: If T
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();
prvalue f()
转换为 xvalue x
.
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 可以通过临时物化转换转换为 xvalues [conv.rval]:
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();
prvalue f()
转换为 xvalue x
.