简介C++11中的左值、纯右值、将亡值

在c++11以后,表达式按值类别,可分为3种:

  • 左值(left value,lvalue)
  • 将亡值(expiring value,xvalue)
  • 纯右值(pure rvalue,pralue)

另,
泛左值(generalized lvalue,glvalue) = 左值 + 将亡值
右值(right value,rvalue) = 纯右值 + 将亡值

以下详细讲解:

左值

左值:能够用&取地址的表达式是左值表达式。

  • 函数名 (实际上是函数指针)
  • 变量名(指的是是具名变量,如: std::cin、std::endl等)
  • 返回左值引用的函数调用,如: std::getline(cin, str), cout << 1
  • 前置运算表达式,如 ++i, --i
  • 由赋值运算符或复合赋值运算符连接的表达式,如: a=b, a+=b,、a%=b
  • 解引用表达式 *p
  • 字符串字面值"abc"
  • 具名的右值引用

这里解释一下“具名的右值引用是左值”。看下面的代码:

    void foo(X&& a)
    {
        X b = a;
        a.data += 1;  // 仍然可以访问a
    }

这里 a 是一个具名的右值引用,在 “X b=a;” 这一句,因为a是左值,所以调用的是X的拷贝构造函数而不是移动构造函数,因此此句之后对a进行访问是没有问题的。而这就是“具名的右值引用是左值”的意义所在。

纯右值

纯右值:纯粹的字面值(如10,True),或者是 求值结果相当于字面值(除字符串)或不具名的临时对象。

  • 字面值(除字符串字面值以外),如: 40, true, nullptr
  • 返回值不是引用类型的函数调用,如: str.substr(1, 2), 2+2
  • 后置运算符表达式,如 i++, i–
  • 算术表达式,如: a+b, a&b, a<<b
  • 逻辑表达式,如: a&&b, a||b, ~a
  • 比较表达式,如: a==b, a>=b, a<b
  • 取地址表达式,即 &a
  • lambda表达式,如: [](int x){return x*x;}
  • 转换目标为非引用类型的cast表达式

将亡值

在C++11之前的右值和C++11中的纯右值是等价的。C++11中的将亡值是随着右值引用(即像int && a 这样的)而引入的。
所谓的“将亡”,当一个右值准备完成初始化或赋值任务时,它就将亡了。
将亡值表达式,就是:

  • 返回右值引用的函数的调用表达式
  • 转换为右值引用的转换函数的调用表达式
    以上二者返回的都是不具名的右值引用。

以下是将亡值:

  • std::move(val)
  • static_cast<X &&>(val) 或 (T&&)val
  • 不具名的右值引用(包括以上二者)

参考文献

(完)

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值