【问题标题】:Lvalue-to-rvalue conversion in [expr.ref]/2[expr.ref]/2 中的左值到右值转换
【发布时间】:2017-08-18 09:22:35
【问题描述】:

[expr.ref]/2:

对于第一个选项(点),第一个表达式应该是一个glvalue 具有完整的类类型。对于第二个选项(箭头)第一个 表达式应为具有指向完整类类型的指针的纯右值。 表达式 E1->E2 被转换为等价形式 (*(E1)).E2; [expr.ref] 的其余部分将仅处理第一个选项 (dot).68 在任何一种情况下,id 表达式都应命名 类或其基类之一。 [ 注:因为一个名字 类被插入到它的类范围内(子句 [class]),一个类的名字 类也被认为是该类的嵌套成员。 —— 尾注 ] [ 注意:[basic.lookup.classref] 描述了如何查找名称 之后 。和 -> 运算符。 — 尾注 ]

根据本段,左值到右值的转换应用于下面sn-p 中的p。但不适用于a。为什么标准规定第一个选项(点)为左值,第二个选项(箭头)为纯右值?

struct A{ void f() {} };
A a;
A* p = new A;
int main() {
    a.f();
    p->f();
}

【问题讨论】:

  • ...为什么应该呢?不清楚你的问题的意义是什么。
  • 我试着记住我是否关心过.-> 左边的表达式是LValue 还是RValue。如果两者都没有重载,则它必须是 LValue(或者不会产生一个地址,而这又是绝对必要的,以应用正确表达式的“偏移量”)。 -> 可能过载。由于重载 -> 运算符的实现,左侧的 RValue 可能就足够了。 (但是,我很难想象一个实际的例子——可能是我缺乏幻想。)运算符. 可能永远不会超载(它被标准禁止)。
  • @Scheff:将. 应用于右值是完全有效的。
  • @Scheff:string("foo").c_str()。这是合法的,尽管返回值不能在它出现的整体语句之外使用。
  • @Scheff string("foo")std::string() 是纯右值。至少,它们在 C++14 中。

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


【解决方案1】:

请记住,prvalues 可以通过临时实现转换 [conv.rval] 转换为 xvalues:

T 类型的纯右值可以转换为T 类型的 xvalue。此转换通过使用临时对象作为其结果评估纯右值,从纯右值初始化 T 类型的临时对象 (15.2) 对象,并产生一个表示临时对象的 xvalue。 T 应该是一个完整的类型。 [注意:如果T是一个类类型(或其数组),它必须有一个可访问且不可删除的析构函数;见 15.4。 — 尾注] [示例

struct X { int n; };
int k = X().n;
// OK, X() prvalue is converted to xvalue

——结束示例]

在引入这种新的右值到右值转换之前,C++14 没有将 后缀表达式 限制为右值。

在这一点上,C++11 是第一个通过(当时)新的右值引用类型实现用户可定义、不受约束的右值到左值转换的版本:auto&& x = f(); 使纯右值 f()转换为 xvalue x

【讨论】:

  • 很好的答案! (+1)
  • 我在解释 [conv.rval] 中的这句话时遇到了一些困难: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, ... .你能详细说明一下吗?
  • @Alexander:从 C++17 开始,我们不再将纯右值视为对象,而是将其视为“制作对象的规则”。要获得一个实际的对象,您需要创建并初始化一个对象,这就是物化过程中发生的事情。文本试图说对象是作为物化转换的结果创建的。这有帮助吗?
  • 当然。感谢您的关注。
  • @KerrekSB 尽管 OP 接受了您的回答,但我仍然认为他的问题没有得到回答。 AFAICT 他在问:Why does the standard prescribe a glvalue for the first option (dot) and a prvalue for the second option (arrow)? 我知道编译器可以通过[expr]/9 将泛右值转换为纯右值,它还可以通过[conv.rval] 将纯右值转换为纯右值。但这并不能回答 OP 的问题?
猜你喜欢
  • 2017-11-24
  • 1970-01-01
  • 2013-07-12
  • 1970-01-01
  • 2014-01-17
  • 1970-01-01
  • 2020-09-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多