§ 3.10.1.5
将prvalue
表达式定义为:
- 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
类似的属性?
答案 0 :(得分:3)
鉴于int f1()
和int && f2()
,decltype(f1())
为int
,而decltype(f2())
为int &&
。这样做的方法是指定f1()
是prvalue,f2()
是xvalue。 decltype
然后查看给定的表达式是否是prvalue,xvalue或lvalue。如果f1()
和f2()
都是xvalues,那么仍然需要以其他方式进行相同的区分。