C++左值和右值

c++中根据表达式使用场景不同,分为左值和右值(其实还有将亡值)。左值的英文简写为“lvalue”,右值的英文简写为“rvalue”。很多人认为它们分别是"left value"、“right value” 的缩写,其实不然。lvalue 是“locator value”的缩写,可意为存储在内存中、有明确存储地址(可寻址)的数据,而 rvalue 译为 “read value”,指的是那些可以提供数据值的数据(不一定可以寻址,例如存储于寄存器中的数据)。
左值和右值主要的区别之一是左值可以被修改,而右值不能。

区分左值和右值
  1. 可位于赋值号(=)左侧的表达式就是左值;反之,只能位于赋值号右侧的表达式就是右值。
  2. 有名称的、可以获取到存储地址的表达式即为左值;反之则是右值。
int a = 10;		// a为左值,10为右值
左值引用

左值引用一个对象,“&”表示的引用称为左值引用

右值引用

一般而言无法对右值进行引用;但是可以使用常量左值引用操作右值
"&&"表示的引用称为右值引用

int b = 3;
int* a = &b;
int& c = 10;	// 编译错误,非常量引用的初始值必须为左值
const int& c = 10;
const int& c = b;
int&& c = 10;	// 右值引用
右值引用使用
  1. 和声明左值引用一样,右值引用也必须立即进行初始化操作,且只能使用右值进行初始化。
int num = 10;
//int && a = num;  //右值引用不能初始化为左值
int && a = 10;
  1. 右值引用可以修改右值
int && a = 10;
a = 11;
cout << a << endl;   //输出结果为11
  1. C++语法之词定义常量右值引用
const int&& a = 10;//编译器不会报错

但这种形式的右值引用并没有实际用处。一方面,右值引用主要用于移动语义和完美转发,其中前者需要有修改右值的权限;其次,常量右值引用的作用就是引用一个不可修改的右值,这项工作完全可以交给常量左值引用完成。

总结

  1. 非常量左值引用可以引用的值的类型只有非常量左值,常量左值引用非常量左值、常量左值及右值
int num = 10;
int& a = num;	//编译成功,非常量左值引用支持引用非常量左值
const int num2 = 100;
int& b = num2;	//编译失败,非常量左值引用不支持引用常量左值
int& c = 10;	//编译失败,非常量左值引用不支持引用右值
 
const int& d = num;		//编译成功,常量左值引用支持引用非常量左值
const int& e = num2;	//编译成功,常量左值引用支持引用常量左值
const int& f = 100;		//编译成功,常量左值引用支持引用右值
  1. 右值引用不支持引用左值;非常量右值引用可以引用的值的类型只有非常量右值,常量右值引用非常量右值、常量右值
int num = 10;
const int num2 = 100;
int&& a = num;	//编译失败,非常量右值引用不支持引用非常量左值
int&& b = num2;	//编译失败,非常量右值引用不支持引用常量左值
int&& c =10;	//编译成功,非常量右值引用支持引用非常量右值
const int&& d = num;	//编译失败,常量右值引用不支持引用非常量左值
const int&& e = num2;	//编译失败,常量右值引用不支持引用常量左值
const int&& f = 100;	//编译成功,常量右值引用支持引用右值
衍生

std::move原型

template <typename T>
typename remove_reference<T>::type&& move(T&& t)
{
	return static_cast<typename remove_reference<T>::type&&>(t);
}
move(arg)
//agr:左值对象,该函数返回arg对象的右值形式

int num = 10;
int&& a = std::move(num);  //编译成功
cout << a << endl;   //输出结果为10;
参考文章

[1] C++(二):如何确定表达式的值类型? - 知乎 (zhihu.com)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值