C ++ 11和C ++ 14标准(分别是工作草案)在§3.10.1中说:
prvalue(“纯”rvalue)是一个不是xvalue的rvalue。 [示例:调用函数的结果 其返回类型不是引用是prvalue。诸如12,7.3e5或true之类的文字的值是 也是一个prvalue。 - 例子]
和
rvalue(历史上所谓的,因为rvalues可能出现在赋值的右侧 表达式)是一个xvalue,一个临时对象(12.2)或其子对象,或一个不相关的值 用一个对象。
这引出了一个问题:表达式如何成为“与对象无关的值”?
我的印象是,表达式的目的是返回对象或void
(我不希望它也是值)。
这些表达式有一些简单而常见的例子吗?
修改1
为了使事情更复杂,请考虑以下事项:
int const& x = 3;
int&& y = 4;
在§8.3.2.5的上下文中,其中包含最有趣的片段:
[...]引用应初始化为引用有效对象或 功能[...]
§8.5.3.1强调了这一点:
宣称为T&的变量。或者T&&,即“对类型T的引用”(8.3.2),应由一个对象初始化, 或类型为T的函数或可转换为T的对象。[...]
答案 0 :(得分:4)
[intro.object]
:
C ++程序中的构造创建,销毁,引用,访问和操作对象。对象是存储区域。 [注意:函数不是对象,无论它是否以对象的方式占用存储。 -end note]一个对象由定义(3.1),new-expression(5.3.4)或实现(12.2)在需要时创建。
所以"与对象无关的值"是不是通过定义或使用new-expression创建的东西,这也意味着它没有相应的存储区域,例如文字。
编辑:字符串文字除外(请参阅注释)
答案 1 :(得分:3)
此类值的示例均为非数组,非类非临时prvalues(临时prvalue对应于临时对象)。示例包括2.0
和1
。反例包括"hello"
(这是一个数组),std::string("haha")
(它是一个类对象)或从float
初始化的2
prvalue临时值,它绑定到(const float&){2}
中的引用{1}}(引用本身是左值!)。我认为这个简单的规则准确地涵盖了规则。
C ++标准关于右值转换左值的脚注说(有点过时,因为它没有修改为提到数组类型)
在C ++类中,prvalues可以具有cv限定类型(因为它们是对象)。这与ISO C不同,其中非左值从不具有cv限定类型。
因此decltype((const int)0)
仍然类型int
的更深层原因是它不引用对象。因为没有对象,所以没有什么可以构造const,因此表达式也永远不会是const。
答案 2 :(得分:1)
这句话的措辞并不尽如人意:
rvalue(历史上所谓的,因为rvalues可能出现在赋值表达式的右侧)是xvalue,临时对象(12.2)或其子对象,或者是与对象无关的值
rvalue是表达式,因此它不能 一个对象(临时或其他)。本引言中关于临时对象的部分的意图是,通过评估rvalue得到的值是一个临时对象,依此类推。
这是一种常见的捷径,例如使用int x;
我们会随便说“x在int中”,而实际上x
是一个标识符;表达式x
的类型为int
,并指定一个int。
无论如何,它将可能的rvalues分为三类:
临时对象的定义包括作为类类型的对象,因此在我看来,“与对象无关的值”应该是非类型的任何非xvalue。例如1 + 1
。