在哪里使用std ::移动弦

Where to use std::move for strings?

本文关键字:移动 std 在哪里      更新时间:2023-10-16

我正在阅读这篇文章。

,我达到了以下代码。

我想知道:

  • std::move对字符串有用(假设字符串足够长)?

  • 它是否使上一个字符串无效?

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

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)

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

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

因此,期望在最坏的情况下可能还有一些其他工作,但是在正常情况下,工作要少得多,因为只完成了一个移动操作而不是副本。

对于std::string,由于其常见的短字符串优化,该参数比其他可移动类型要困难得多:而不是一些指针操作,可能需要传输字节。但是,在实践中,复制短字符串或指针实际上只是一个memcpy(),然后可能是操作,表明移动操作的源不再包含需要发布的字符串。

因此,简单的规则是

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

移动字符串时会消耗旧值:

  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现在将包含一些"有效的未指定值"。示例输出包含空字符串,但您不应依靠此字符串。

也许是XML的1MB的不必要克隆。