为什么返回非引用类型的函数表达式被认为是prvalues而不是xvalues?

时间:2017-02-04 17:37:29

标签: c++ language-lawyer

标准中的

§ 3.10.1.5prvalue表达式定义为:

  

- prvalue(“纯”rvalue)是一个不是xvalue的rvalue。 [示例:调用函数的结果   其返回类型不是引用是prvalue。诸如12,7.3e5或true之类的文字的值是   也是一个prvalue。 - 结束例子]

因此,函数foo()prvalue表达式:

class Foo {}; 
Foo foo() { return Foo{}; }

要初始化lvalue reference to a non-volatile const type / rvalue reference初始值设定项表达式必须为(§ 5.2.1.1):

  

[...] xvalue(但不是位字段),类prvalue,数组prvalue或函数lvalue和“cv1 T1”   与“cv2 T2”或[...]

参考兼容

因此,

Foo &&rrFoo_ = foo(); 

是有效代码,其中rrFoo_绑定到延长对象生命周期的临时对象(§12.2):

  

类类型的临时代码在各种上下文中创建:绑定对prvalue的引用(8.5.3),返回   prvalue(6.6.3),一个创建prvalue(4.1,5.2.9,5.2.11,5.4),抛出异常(15.1)的转换,   在一些初始化(8.5)。

如上所述并且忽略了RVO,以下类型Foo对象的初始化将从默认构造对象复制移动构造临时。然后用于复制移动的临时对象构造名为obj_foo的最终对象:

Foo obj_foo{ foo() }; 

因此,在这两种情况下,我们要么窃取,要么延长临时对象的生命周期,否则会被破坏。

§3.10.1.2将xvalues定义为:

  

xvalue(“eXpiring”值)也指一个对象,通常接近其生命周期的末尾(因此它的   例如,可以移动资源。 [...]

我无法想到没有创建临时对象的情况。所以我的问题是,为什么像foo()这样的函数表达式被认为是prvalue表达式,甚至认为它们至少xvalues类似的属性?

1 个答案:

答案 0 :(得分:3)

鉴于int f1()int && f2()decltype(f1())int,而decltype(f2())int &&。这样做的方法是指定f1()是prvalue,f2()是xvalue。 decltype然后查看给定的表达式是否是prvalue,xvalue或lvalue。如果f1()f2()都是xvalues,那么仍然需要以其他方式进行相同的区分。