在哪里使用std :: move for strings?

时间:2017-12-16 01:00:03

标签: c++ c++11 stdmove

我正在阅读post

我达到了以下代码。

我在想:

  • class Name { public: Name(std::string firstName, std::string lastName) : firstName_(std::move(firstName)) , lastName_(std::move(lastName)) {} void print() const { std::cout << lastName_ << ", " << firstName_ << '\n'; } private: std::string firstName_; std::string lastName_; }; 对字符串有用(假设字符串足够长)吗?

  • 是否会使之前的字符串无效?

  • 我应该在哪里使用它?我应该在哪里使用它?

constructor(const std::string& argument): field(argument)

我的技术一直在使用

{{1}}

2 个答案:

答案 0 :(得分:2)

当可移动类型的值消耗时,按值接受参数的习惯是有意义的。使用消耗值,我的意思是该值转发到需要自己的值副本的东西。原因在于:

  • 当通过值传递参数时,可以省略副本,例如,当参数是不同函数调用的结果时。即使不能删除副本,也可能使参数看起来像是临时的(例如,使用std::move(arg))。
  • 由于值已传递到函数中,即函数已拥有副本,因此可以在需要的任何地方转发此值。
  • 在最坏的情况下,参数会被复制,但由于需要一个值,因此需要从T const&参数创建一个副本,并且假设额外的移动操作相对便宜。

因此,期望在最坏的情况下可能会有一些额外的工作,但在正常情况下,由于只进行一次移动操作而不是复制,所以工作量大大减少。

对于std::string,由于其非常常见的短字符串优化,该参数比其他可移动类型稍微强一些:代替几个指针操作,可能需要传输字节。但是,实际上,复制短字符串或指针实际上只是一个memcpy(),可能后跟一个操作,表明移动操作的源不再包含需要释放的字符串。

因此,简单的规则是

  

当使用可移动对象时,按值接受参数并移动对象而不是通过T const&传递参数并创建副本以使用结果。

答案 1 :(得分:0)

移动字符串时消耗旧值:

  std::string sa = "Was the string";
  std::string sb = std::move(sa);
  std::cout << "Old [" << sa << "] new [" << sb << "]" << std::endl;

输出: 旧的 [] 新的 [是字符串]

我假设,旧值无需复制即可进入新字符串。当您需要在某些结构中分配字符串字段以作为参数传递时,这应该很有效,例如在 ROS 中:

  std::string my_message = method_that_returns_just_a_string();
  std_msgs::String message;
  message.data = std::move(my_message);

my_message 现在将包含一些“有效的未指定值”。示例输出包含空字符串,但您不应依赖于此。

无需克隆 1Mb 的 XML。