标准库move函数是使用右值引用的模板的一个很好的例子。标准库是这样定义std::move的:

template <typename T>
typename remove_reference<T>::type&& move(T&& t)
{
return static_cast<typename remove_reference<T>::type&&>(t);
}

我们考虑如下代码的工作过程:

std::string s1("hi"), s2;
s2 = std::move(string("hi")); // 正确,从一个右值移动数据
s2 = std::move(s1); // 正确,但是在赋值之后,s1的值是不确定的

在第一个赋值中,实参是string类型的右值,因此过程为:

  • 推断T的类型为 string
  • remove_reference<string> 的 type 成员是 string
  • move 返回类型是 string&&
  • move 的函数参数t的类型为 string&&

因此,这个调用实例化 move<string>,即函数

string&& move(string &&t)

在第二个赋值中,实参是一个左值,因此:

  • 推断T的类型为 string&
  • remove_reference<string&> 的 type 成员是 string
  • move 返回类型是 string&&
  • move 的函数参数t的类型为 string& &&,会折叠成 string&

因此,这个调用实例化 move<string&>,即

string&& move(string &t)

  通常情况下,static_cast 只能用于其他合法的类型转换。但是有一条针对右值的特许规则:虽然不能隐式的将一个左值转换成右值引用,但我们可以用static_cast显示的将一个左值转换为一个右值。

C++ Primer 笔记——理解std::move的更多相关文章

  1. item 23: 理解std::move和std::forward

    本文翻译自<effective modern C++>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 根据std::move和std::forward不 ...

  2. std::move的原理与实现,右值引用的深入理解

    这次我真的懂了.... 首先C++11引入了右值引用 && ‘&&’这个要连起来看,是一个整体,C++多了一个关键字而已. 不是引用的引用.是船新的一种语法.那有什么用 ...

  3. 透彻理解C++11新特性:右值引用、std::move、std::forward

    目录 浅拷贝.深拷贝 左值.右值 右值引用类型 强转右值 std::move 重新审视右值引用 右值引用类型和右值的关系 函数参数传递 函数返还值传递 万能引用 引用折叠 完美转发 std::forw ...

  4. C++ Primer笔记

    C++ Primer笔记 ch2 变量和基本类型 声明 extern int i; extern int i = 3.14;//定义 左值引用(绑定零一变量初始值,别名) 不能定义引用的引用:引用必须 ...

  5. C++ 11 左值,右值,左值引用,右值引用,std::move, std::foward

    这篇文章要介绍的内容和标题一致,关于C++ 11中的这几个特性网上介绍的文章很多,看了一些之后想把几个比较关键的点总结记录一下,文章比较长.给出了很多代码示例,都是编译运行测试过的,希望能用这些帮助理 ...

  6. Item 25: 对右值引用使用std::move,对universal引用则使用std::forward

    本文翻译自<effective modern C++>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 右值引用只能绑定那些有资格被move的对象上去.如 ...

  7. std::move 移动对象资源

    场景: C++ 标准库使用比如vector::push_back 等这类函数时,会对参数的对象进行复制,连数据也会复制.这就会造成对象内存的额外创建, 本来原意是想把参数push_back进去就行了. ...

  8. 关于C++11中的std::move和std::forward

    std::move是一个用于提示优化的函数,过去的c++98中,由于无法将作为右值的临时变量从左值当中区别出来,所以程序运行时有大量临时变量白白的创建后又立刻销毁,其中又尤其是返回字符串std::st ...

  9. C++ 函数返回局部变量的std::move()的适用场景(转)

    作者:神奇先生链接:https://www.zhihu.com/question/57048704/answer/151446405来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...

随机推荐

  1. SpringMVC中JSONP的基本使用

    @RequestMapping("/check/{param}/{type}") @ResponseBody public Object checkData(@PathVariab ...

  2. struts文件下载机制

    Struts2 中使用 type="stream" 的 result 进行下载即可.只用提供一个输入流inputStream,剩下的输出工作struts帮我们做. 例子一: 1.可 ...

  3. mysql 二进包在linux下安装过程

    cp mysql-5.6.17-linux-glibc2.5-i686 /usr/local/mysql -r groupadd mysql和useradd -r -g mysql mysql 进入安 ...

  4. mac配置supervisor

    mac配置supervisor 安装 brew install supervisor 启动 一种是手动 supervisord -c /usr/local/etc/supervisord.ini 让s ...

  5. C++ 读取字符串中的数字

    今天真是试了各种方法,笨方法聪明方法都有了 方法1:一个字符一个字符的读取 方法2:借助strtok实现split 适用于char 方法3:借助istringstream实现split 适用于stri ...

  6. webstorm加载项目卡死在scanning files to index

    今天用webstorm导入项目时,需要加载node-modules文件夹,导致webstorm非常卡,页面提示scanning files to index... 网上搜到办法,记录下: 说明: 在n ...

  7. openvpn 给客户端固定隧道IP地址

    openvpn 客户端拿到的ip地址是服务器端随机分配的,因此需要远程ssh到一个终端时,它的ip地址有时会变,如何给他固定IP地址呢. 方法如下: 1) 在服务器端使用的配置文件 server.co ...

  8. CSS rem长度单位

    1. 概述 1.1 说明 rem是css3中新增的一个单位属性(font size of the root element),根据页面的根节点(html)的字体大小进行转换的单位,通过此单位属性可以进 ...

  9. SqlBulkCopy 之 Received an invalid column length from the bcp client for colid 5.

    SqlBulkCopy 批量复制报错: Received an invalid column length from the bcp client for colid 5. 翻译:从bcp客户端收到一 ...

  10. 开源巨献:年度最佳 JavaScript 和 CSS 开源库推荐!

    作者:编辑部的故事   <  开源巨献:年度最佳 JavaScript 和 CSS 开源库推荐!   > 开源巨献:年度最佳 JavaScript 和 CSS 开源库推荐! Tutoria ...