经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
c11 move 和 forward
来源:cnblogs  作者:Ultraman_X  时间:2021/5/10 9:06:01  对本文有异议

c++11 : move forward 个人理解

右值引用(rvale references)和全局引用(universal references)的区别:

T&&”有两种意思:

  1. 代表的是右值引用(rvalue reference)。就是他绑定到一个右值上,代表对象的移动来源。

2.代表可能是右值引用也可能是左值引用。叫做全局引用。

全局引用使用在两个地方:

1.函数模板:

  1. template<typename T> void f(T&& param) //param is a universal reference

2.auto 的使用:

  1. auto&& var2 = var1;

使用右值引用(T&& 第一种意思)的情况:

  1. void f(Widget&& param) // no type deduction param is an rvalue reference
  2. Widget&& var1 = Widget(); // no type deduction param is an rvalue reference

特殊情况:

  1. 虽然T需要类型推理,但是param是vector不是"T&&"
  1. template<typename T>
  2. void f(std::vector<T>&& param) // param is an rvalue reference
  1. 对与const关键字:
  1. template <typename T>
  2. void f(const T&& param); //param is an rvalue reference

std::move使用在rvalue reference std::forward使用在universal reference

很严重的错误是将std::move应用到universal reference:会造成修改左值这样不愿意看到的错误:

  1. class Widget{
  2. pulibc:
  3. templtea <typename T>
  4. void setName(T&& newName) //universal reference
  5. {
  6. name = std::move(newName); //compiles ,but is bad bad bad
  7. }
  8. ...
  9. private:
  10. std::string name;
  11. }
  12. std::string getWidgetName();
  13. Widget w;
  14. auto n = getWidgetName(); // moves n into w!
  15. w.setName(n); //n's vale now unkonow;

这样最后n的值变成不确定状态了。也许是觉得使用两个函数重载:

  1. class Widget{
  2. public:
  3. void setName(const std::string& newname){name = newName;}
  4. void set(std::string&& newName) {name = std::move(newName);}
  5. }

这种情况也是可以的。但是有缺点是这中方式不是很有效。会有很多std::string 的构造函数,析构函数,复制构造函数的调用过程。同时会增加代码量。还有一个更严重的问题是代码设计问题。现在只是一个参数就需要连个函数,如果函数接收参数过多,这样会需要跟多的重载函数。

对应std::move 和 std::forward的理解:


std::move 和std::forward只是一个函数,该函数进行cast操作。move是无条件的转换为右值,而forward是有条件的转换。

当然,右值只是作为一个moving的候选:

  1. class Annotation{
  2. public :
  3. explicit Annotation(const std::string text):
  4. value(std::move(text)) // "move "text into value,this code doesn't do what it seems to!!
  5. {...}
  6. private:
  7. std::string value;
  8. }

"text"并没有被moved into value,而是被复制。虽然text被move转为了右值,但是text被声明为const std::string,转化为const std::string的右值,但是:

  1. class string{
  2. public:
  3. ...
  4. string (const string&rhs); //copy ctor
  5. string (string&& rhs); //move ctor
  6. }

const std::string右值无法作为std::string 的move 构造函数。不过可以作为拷贝构造函数参数。因为lvalue-reference-to-const是运行邦迪哦那个到const rvalue。

所以得出两条结论:

  • 不要将一个对像设置为const,如果你希望该从对象moving。
  • std::move 并不移动任何东西,而去也不保证被cast的东西真正被moved。唯一确定的是std::move把他转换为右值。

std::forward是有条件的转换:只有当参数是右值的时候才被转换为右值。

原文链接:http://www.cnblogs.com/ultramanX/p/14745617.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号