脚本宝典收集整理的这篇文章主要介绍了右值引用,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
右值引用
1. 什么是左值和右值
有几种区分方法:
- 左值就是即能出现在等号左边也能出现在等号右变的变量(表达式), 右值就只能出现在等号的右边
- 能取地址的就是左值,不能取地址的就是右值
int i, j, k;
i = 1; // i是左值, 1是右值
i = j; // i, j 都是左值 1 = i; // 错误, 1是右值
2. 什么是左值引用和右值引用
int i = 0;
int& j = i; // j为左值引用
int& k = 1; // 错误,右值是不可修改的,所以k被绑定到1是语法错误
const int& k2 = 1 // 正确,const 左值引用不能被修改
int i = 0;
int&& j = i; // 错误,右值引用不能绑定到左值上
int&& k = 1; // 正确
int&& k2 = i + 42; // 正确, i + 42是右值
int& k3 = i + 42; // 错误
3.右值引用它要解决什么问题,怎么使用
c++11引入右值引用主要解决两个问题:
1.对需要拷贝的临时对象(右值)
进行移动
操作,提升效率
在c++11以前,因为想避免深拷贝的性能损失,我们把本应该写成
vector<int> GetResource(int args); // (1)
写成了
void GetResouce(int args, vector<int>* output); // (2)
在c++中,我们可以大胆的写成(1)这种形式,如果返回的是栈对象,就会优先调用移动构造函数,而不是拷贝构造函数
在我们写函数声明的时候,只有当:
@H_406_177@
函数内需要copy参数时
需要将参数保存到栈外内存时
我们可以把参数声明为右值引用,比如标准库里的vertor
的push_back
void push_back(const T& v);
void push_back(T&& v);
如果只满足第一个条件,我们可以使用
void Func(const T& v)
{
// 这里直接调用一次copy构造函数
local l = v;
}
2.在模板函数中按参数的实际类型进行转发
void Fun(const int&)
{
std::cout << "lvalue" << std::endl;
}
void Fun(int&& i)
{
std::cout << "rvalue" << std::endl;
}
template <typename T>
void ForwardValue(T&& v)
{
// 使用forward把值的类型原样转发给Fun
Fun(std::forward<T>(v));
}
int main()
{
ForwardValue(1);
int a = 1;
ForwardValue(a);
return 0;
}
以上是脚本宝典为你收集整理的右值引用全部内容,希望文章能够帮你解决右值引用所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。