【问题标题】:Are temporary objects xvalues?临时对象是 xvalues 吗?
【发布时间】:2012-03-12 16:28:02
【问题描述】:

我目前正在写我的学位论文,它还涉及对 C++11 背后理论的一些解释,这真的很好,因为 C++ 是我选择的编程语言,并且该标准或多或少是免费提供的 (N3337)让自己迷失。

然而,当我试图准确而详细地解释新的 xvalue 类别时,我碰壁了。 据我了解,临时对象始终是 xvalue,但我在标准中找不到对此的任何引用。据我了解,函数调用的函数表达式的值类别具有非引用返回类型,是一个 xvalue。该标准说“xvalue 是某些涉及右值引用的表达式的结果”,这让我很烦恼。例如:

TestClass { ... };
testClass createObject() { return testClass(); }

void someFunction(TestClass& testClass) { ... }
void someFunction(TestClass&& testClass) { ... }

someFunction(createObject());

如预期的那样,上面将调用以右值引用作为参数的重载函数。然而 createObject() 不返回一个右值引用,它返回一个 TestClass 类型的临时对象。我的问题是现在,我必须解释它背后的原因。表达式“createObject()”的计算结果是什么?如果它确实是一个 xvalue,因为它返回一个临时对象,那么它背后的原因很清楚,并且在重载决议期间,右值引用更受青睐。如果没有,关于标准的这种行为的解释是什么?是否在某处定义了一些我尚未找到的隐式转换逻辑?

如果有人可以帮助我解决这个问题,我将非常感激,因为即使经过几天的挖掘和阅读,我还没有提出合理的解释。提前非常感谢。

【问题讨论】:

标签: c++ c++11 rvalue-reference xvalue


【解决方案1】:

对象永远不是 {l|r|x} 值。值类别描述表达式

xvalue 是函数调用表达式的值类别,其中函数返回类型是对对象的右值引用(例如std::move),它也是强制转换表达式的值类别,其中强制转换是对对象的右值引用(例如 std::move 的内脏)。

您示例中的函数调用表达式createObject() 是一个prvalue 表达式,因为它是对具有非引用返回类型的函数的函数调用。

【讨论】:

  • 我知道类别只适用于表达式。 :) 对不起,我的帖子不清楚,会立即更正。我现在是不是觉得自己很蠢——真的很蠢。我不知道我在想什么,期望具有非引用返回类型的函数调用的表达式是 xvalue。非常感谢。我现在最好走开躲起来...... :(
  • “对象永远不是 {l|r|x} 值。” 但是 xvalues 表示一个对象通常接近其生命周期的尽头。因此,如果我有T t = T(),则T() prvalue 将转换为xvalue;此 xvalue 指的是 T 类型的临时值。这隐含地类似于T _tmp{}; T t = _tmp。第一个_tmp 是左值表达式。最后一个_tmp 是xvalue 表达式。我说的对吗?
  • @cpper 它是隐式的(或显式的,如果你查看生成的 AST)类似于T t = materialize( T() ),其中 T() 是右值,materialize(T()) 是 xvalue。我不关注评论的 _tmp 部分。
  • 标准中是否存在materialize()(方法?)?请你给我一个参考来阅读吗?
  • @cpper 不,它作为 AST 中的一个节点存在该标准只是对其在 [conv.rval] 中的作用的口头描述
猜你喜欢
  • 2019-06-17
  • 2014-10-13
  • 2019-02-28
  • 1970-01-01
  • 1970-01-01
  • 2011-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多