什么是右值,左值,xvalues,glvalues和prvalues?
在C ++ 03中,表达式是右值或左值 。
在C ++ 11中,表达式可以是:
两类分为五类。
我想这个文件可能不是那么简短的介绍:n3055
整个屠杀始于移动语义。 一旦我们有了可以移动但不被复制的表达式,突然容易掌握的规则就要求区分可以移动的表达式和在哪个方向上。
根据我对草案的看法,r / l值的区别保持不变,只是在移动东西时变得混乱。
他们需要吗? 如果我们想放弃新功能,可能不会。 但为了实现更好的优化,我们应该拥抱它们。
引用n3055:
E
是指针类型的表达式,然后*E
是一个左值表达式参考对象或函数,其E
点。 作为另一个例子,调用返回类型为左值引用的函数的结果是一个左值。] 所讨论的文件对于这个问题来说是一个很好的参考,因为它显示了标准中引入新术语后发生的确切变化。
这些新的表达类别是什么?
FCD(n3092)有很好的描述:
- 一个左值(所谓的,历史上,因为左值可能出现在赋值表达式的左侧)指定一个函数或一个对象。 [例如:如果E是指针类型的表达式,则* E是指向E指向的对象或函数的左值表达式。 作为另一个例子,调用返回类型是左值引用的函数的结果是左值。 - 例子]
- 一个xvalue(一个“eXpiring”值)也指对象,通常接近其生命周期结束时(例如,可以移动它的资源)。 xvalue是涉及右值引用的某些表达式的结果(8.3.2)。 [例子:调用返回类型是右值引用的函数的结果是一个xvalue。 - 例子]
- 一个glvalue(“广义”左值)是一个左值或一个xvalue。
- 一个右值(在过去称为,因为右值可能出现在赋值表达式的右侧)是一个xvalue,一个临时对象(12.2)或其子对象,或一个与对象无关的值。
- 一个prvalue(“纯”右值)是一个不是xvalue的右值。 [例子:调用返回类型不是引用的函数的结果是一个prvalue。 诸如12,7.3e5或true这样的字面值也是一个值。 - 例子]
每个表达式都属于该分类中的基本分类之一:左值,左值或右值。 表达式的这个属性被称为它的值类别。 [注:在第5章中讨论每个内置运算符都指出了它产生的值的类别以及它期望的操作数的值类别。 例如,内置赋值运算符期望左操作数是左值,右操作数是前值,并产生左值作为结果。 用户定义的运算符是函数,它们期望的值的类别和产出取决于它们的参数和返回类型。 - 结束注释
我建议你阅读整节3.10左值和右值 。
这些新类别如何与现有的右值和左值类别相关联?
再次:
C ++ 0x中的右值和左值类别与C ++ 03中的相同吗?
rvalues的语义特别是随着移动语义的引入而发展。
为什么需要这些新类别?
所以这一举措的建设/任务可以被定义和支持。
我将从最后一个问题开始:
为什么需要这些新类别?
C ++标准包含许多处理表达式值类别的规则。 一些规则区分了左值和右值。 例如,涉及重载分辨率。 其他规则区分了glvalue和prvalue。 例如,可以使用不完整或抽象类型的glvalue,但没有不完整或抽象类型的prvalue。 在我们使用这个术语之前,实际上需要区分glvalue / prevalue是指左值/右值的规则,它们或者是无意的错误,或者是包含了很多解释和例外规则,a“......除非右值是由于未命名右值引用...“。 所以,给予他们自己的名字的价值和价值的概念似乎是一个好主意。
这些新的表达类别是什么? 这些新类别如何与现有的右值和左值类别相关联?
我们仍然有与C ++ 98兼容的术语左值和右值。 我们刚刚将rvalues分成两个子组,xvalues和prvalues,我们将lvalues和xvalues称为glvalues。 Xvalues是未命名右值引用的一种新的值类别。 每个表达式都是以下三个表达式之一:左值,左值,右值。 维恩图如下所示:
______ ______
/ X
/ /
| l | x | pr |
/ /
______X______/
gl r
功能示例:
int prvalue();
int& lvalue();
int&& xvalue();
但是也不要忘记,有名的右值引用是左值:
void foo(int&& t) {
// t is initialized with an rvalue expression
// but is actually an lvalue expression itself
}
链接地址: http://www.djcxy.com/p/2003.html
上一篇: What are rvalues, lvalues, xvalues, glvalues, and prvalues?
下一篇: What is the copy