这篇文章主要讲解了“c++11 左值引用和右值引用的用法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“c++11 左值引用和右值引用的用法”吧!
左值是表达式结束后依然存在的持久对象,既能出现在等号左边也能出现在等号右边的变量或表达式
右值是因为声明结束后会被销毁,所以不能放在等号左边
#include <iostream>
using namespace std;
void Print(string& s){
cout << s;
}
int main(){
string s="abc";
Print(s); // OK
Print("abc"); // parse error
}
&是c++里的左值引用
&&是c11里的右值引用
右值只能被const引用指向,在这时,右值的生命周期被延长了,直到引用销毁。
因为右值只能被const引用指向,所以我们才会在拷贝构造函数和赋值函数形参内加上const(还有一个原因是避免参数被修改),这里c11出现了一个特殊智能指针的non const拷贝构造函数
string Proc()
{
return string("abc");
}
int main()
{
const string& ref = Proc();
//此时右值的生命周期延长了,直到main函数结束
cout << ref << endl;
return 0;
}
使用std::move()接受一个参数,返回该参数对应的右值引用
template<typename _Tp>
inline typename std::remove_reference<_Tp>::type&& move(_Tp&& __t)
{
return static_cast<typename std::remove_reference<_Tp>::type&&>(__t);
}
static_cast是一个强制类型转换符,强制类型转换会告诉编译器:我们知道并且不会在意潜在的精度损失。
//下面有一个move使用的小例子
void swap(T& a, T& b)
{
T tmp = move(a);
a = move(b);
b = move(tmp);
//可以看出相比较之前的进行了多次资源拷贝、销毁的swap
//在swap里使用move只是进行了三次的指针交换,效率提升
}
forward()接收一个参数,返回该参数本来所对应的类型的引用。(即完美转发)
#include <iostream>
//#include <utility> //for std::forward
using namespace std;
void print(const int& t)
{
cout <<"lvalue" << endl;
}
void print(int&& t)
{
cout <<"rvalue" << endl;
}
template<typename T>
void Test(T&& v) //v是Universal引用
{
//不完美转发
print(v); //v具有变量,本身是左值,调用print(int& t)
//完美转发
print(std::forward<T>(v)); //按v被初始化时的类型转发(左值或右值)
//强制将v转为右值
print(std::move(v)); //将v强制转为右值,调用print(int&& t)
}
int main()
{
cout <<"========Test(1)========" << endl;
Test(1); //传入右值
int x = 1;
cout <<"========Test(x)========" << endl;
Test(x); //传入左值
cout <<"=====Test(std::forward<int>(1)===" << endl;
Test(std::forward<int>(1)); //T为int,以右值方式转发1
//Test(std::forward<int&>(1)); //T为int&,需转入左值
cout <<"=====Test(std::forward<int>(x))===" << endl;
Test(std::forward<int>(x)); //T为int,以右值方式转发x
cout <<"=====Test(std::forward<int&>(x))===" << endl;
Test(std::forward<int&>(x)); //T为int,以左值方式转发x
return 0;
}
/*输出结果
e:\Study\C++11\16>g++ -std=c++11 test2.cpp
e:\Study\C++11\16>a.exe
========Test(1)========
lvalue
rvalue
rvalue
========Test(x)========
lvalue
lvalue
rvalue
=====Test(std::forward<int>(1)===
lvalue
rvalue
rvalue
=====Test(std::forward<int>(x))===
lvalue
rvalue
rvalue
=====Test(std::forward<int&>(x))===
lvalue
lvalue
rvalue
*/
感谢各位的阅读,以上就是“c++11 左值引用和右值引用的用法”的内容了,经过本文的学习后,相信大家对c++11 左值引用和右值引用的用法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/u/347414/blog/3118118