C++11 中的左值、右值和将亡值

2018-04-07  本文已影响220人  georgeguo

C++98 中表达式值的类型只有左值和右值两种类型,可以取到地址的表达式就是左值,不是左值的值就是右值,而C++11中将表达式的值类型划分成了lvalue(左值)、rvalue(右值)、prvalue(纯右值)、xvalue(将亡值)、gvalue(泛左值) 5种。下文从基本概念并结合实际的例子区分C++11中的表达式值类型。

基本概念

表达式

值类别

  • C++11中右值rvalue的概念包括两个部分:
    1. 将亡值(xvalue. expiring value),xvalue是C++11新增的概念,与右值引用相关的表达式,如: 将要被移动的对象、T&&函数返回值、std::move返回值和转换为 T&&的类型的转换函数的返回值等;
    2. 纯右值(pvalue, pure right value),如: 非引用返回的临时变量、运算表达式产生的临时变量、原始字面量和lambda表达式等属于pvalue;

注意:“左值”是表达式的结果的一种属性,但更为普遍地,通常用“左值”来指代左值表达式。所谓左值表达式,就是指求值结果的值类别为左值的表达式。在后文中,我们依然用左值指代左值表达式。对于纯右值和将亡值,亦然。

左值、纯右值和将亡值的描述

左值

一个区分左值和右值的便捷方法:看能不能对表达式取地址,若能,则为左值,若不能则为右值。所有的具名变量都是左值,而右值是不具名的。

纯右值

将亡值

在C++11中,用左值去初始化一个对象或为一个已有对象赋值时,会调用拷贝构造函数或拷贝赋值运算符来拷贝资源,而当用一个右值(包括纯右值和将亡值)来初始化或赋值时,会调用移动构造函数或移动赋值运算符来移动资源,从而避免拷贝,提高效率。当该右值完成初始化或赋值的任务时,它的资源已经移动给了被初始化者或被赋值者,同时该右值也将会马上被销毁(析构)。也就是说,当一个右值准备完成初始化或赋值任务时,它已经“将亡”了。这种右值常用来完成移动构造或移动赋值的特殊任务,扮演着“将亡”的角色,所以C++11给这类右值起了一个新的名字——将亡值。

C++11中值的类型总结

对比说明

情况1: ++i是左值,而i++是右值

情况2: 解引用表达式*p是左值,取地址表达式&a是纯右值

情况3: a+b、a&&b、a==b都是纯右值

情况4: 字符串字面值是左值,而非字符串的字面量是纯右值

情况5: 具名的右值引用是左值,不具名的右值引用是右值。

继续深入学习

C++11中的右值引用和移动语义

参考

上一篇 下一篇

猜你喜欢

热点阅读