C++ 右值引用
来源:互联网 发布:中超风云球员数据 编辑:程序博客网 时间:2024/04/28 16:55
右值引用
今天平安夜,要不是女巫用药,要不是狼人一刀刀长老身上了。。。
开个玩笑。。。
- 右值引用
- 起源
- 左值右值
- 右值引用的应用
- 参考
起源
因为同学的大作业看了看模板类,可能以前学得也比较糙,也有可能之前用的书没有讲到C++ 11的新特性所以并没有注意到这个概念,直到看到如下代码《C++ Primer》(第5版)584页:
template <typename T> class Blob{public: //... void push_back(T &&t);//移动版本 //...};
居然第一次看到双取地址符的写法,一下子把我看呆了,都不知道怎么查。。StackOverFlow上面显然有人跟我遇到了一样的问题,http://stackoverflow.com/questions/4549151/c-double-address-operator。。这种写法就代表右值引用(rvalue reference)
左值右值
说起这个真的是个非常让人头疼的概念:
左值是一个指向某内存空间的表达式,并且可以通过&获取内存,而右值就是非左值。这种解释真是让人云里雾里的,简单的来说,“左值既可以在赋值号的左边也可以在赋值号的右边,而右值只能出现在右边。”,这个论断在大多数情况下是有效的,比如说:
int a=10;int b=(a+1);//b是左值int c=b;a+1=c;//error a+1是右值
再举个例子说:
在编译器里面敲下如下代码:
int i=1;++(i++);//编译器报错
这里错误提示:表达式必须是可修改的左值,而如果这样写:
int i =1;(++i)++;
就没有问题。
说远点,以前有人问i++
,和++i
两个表达式究竟哪个效率高?
http://stackoverflow.com/questions/24853/what-is-the-difference-between-i-and-i
一个说法是++i
效率高,因为++i
返回左值,并不进行拷贝操作,而i++
返回的则是右值。
仔细研究这两个表达式的过程就更加清晰了:
//i++{ int temp = i; i=i+1; return temp;}//++i;{ i=i+1; return &i;}
想起之前学习const的时候说过一点c++ const限定符,因为必须将左值绑定到引用上,但是使用常量引用去“绑定”一个右值,示例:
int &i=1;//error 非常量引用的初始值必须为左值const int &i=1;//ok相当于{ const int temp=1; const int &i = temp;}
扯远了,简单的理解,左值是一个对象,右值是一个值。
右值引用的应用
加入右值引用的概念,当然要跟左值引用区分了,其实左值引用就是我们之前认知世界中的引用,而新标准中为了区分左值右值引用,用双取地址符(&&)来指代右值引用,其好处是可以实现移动语义(Move Sementics)和精确传递(Perfect Forwarding),回到最早提到的关于push()
函数的移动版本:
template <typename T> class Blob{public: //... void push_back(T &&t);//移动版本 //...};
在使用时,我们要额外使用新标准提供的std::move()
函数:强制实现转移语义,直接使用变量的返回值,并强制认为是一个右值,这个函数也将返回该右值引用。在某些编译换进下,move()
函数还起到了swap()
的功能:
std::string str = "Hello";std::vector<std::string> v;v.push_back(str);v.push_back(std::move(str));
通过单步调试观察string str
,和vector<string> v
的值,结果如下:
单步调试结果1
单步调试结果2
在使用移动语义的时候发现
str
的为空了,这是因为作为一个右值,他已经return
了。参考
http://en.cppreference.com/w/cpp/utility/move
http://www.cplusplus.com/reference/utility/move/
http://www.zhihu.com/question/22111546
http://jxq.me/2012/06/06/%E8%AF%91%E8%AF%A6%E8%A7%A3c%E5%8F%B3%E5%80%BC%E5%BC%95%E7%94%A8/
- c++move语义与右值引用
- C++:右值引用与移动构造
- [C++]右值引用和转移语义
- C++primer学习笔记--右值引用
- [C++]C++11右值引用
- 【C++】右值引用与模板
- C++——左值引用和右值引用
- C++——左值引用和右值引用
- C++/C++11中左值、左值引用、右值、右值引用的使用
- 右值引用
- 右值引用
- C++右值引用
- 右值引用
- 右值引用
- C++右值引用
- C++ 右值引用
- C++右值引用
- c++ 右值引用
- [leetcode] 102. Binary Tree Level Order Traversal 解题报告
- 网络抓取页面乱码
- Python爬虫学习系列教程
- android音乐播放器,可进度条调节
- Miller_Rabin 大素数判断
- C++ 右值引用
- 【AC自动机】hdu2222 hdu2896 hdu3065 zoj3430 poj2778 hdu2243
- 最大连续和(分治法)
- linux 每次关机后重启都要手动source /etc/profile
- 关于控件getWidth和getHeight方法都为0的解释及解决方法
- leetcode刷题日记——Linked List Cycle
- Java之美[从菜鸟到高手演变]系列之博文阅读导航
- Java中 FileReader的中文乱码问题
- Android实战之 Jmail发送邮件(无需跳转到邮件客户端)