c++ - [expr.ref]/2 中的左值到右值转换

标签 c++ language-lawyer c++17 lvalue-to-rvalue

[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 可以通过临时物化转换 [conv.rval] 转换为 xvalues:

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() ; 使纯右值 f() 变成一个 xvalue x

关于c++ - [expr.ref]/2 中的左值到右值转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43016421/

相关文章:

c++ - boost::function 和 boost::bind 是如何工作的

c++ - C++20 标准对使用子对象作为模板非类型参数有什么看法?

c++ - gcc:通过显式 memcpy 避免严格别名违规警告

c++ - 当 GCC 正常时 Clang 报告 "constexpr if condition is not a constant expression"

c++ - 使用折叠表达式初始化静态 constexpr 类数据成员不编译

c++ - 无法使用 OOP C++ 打印堆栈项

c++ - 如何将 std::queue 转换为 std::vector

c++ - 为什么 `const` 指向函数的指针在常量表达式中不可用?

c++ - 令人费解的非尾随参数包行为

C++ 返回数组并将其分配给变量