Where to use std::move for strings?

ar2*_*015 15 c++ c++11 stdmove

I was reading this post.

And I reached to the following code.

I was wondering:

  • Is std::move useful for strings (assuming the string is long enough)?

  • Does it invalidate the previous string?

  • Where should I use it and where I should not?

.

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_;
};
Run Code Online (Sandbox Code Playgroud)

My technique was always using

constructor(const std::string& argument): field(argument)
Run Code Online (Sandbox Code Playgroud)

Die*_*ühl 12

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

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

因此,预期在最坏的情况下可能会有少量的额外工作,但在正常情况下,工作量会大大减少,因为只完成了一个移动操作而不是复制。

对于std::string该说法是稍微比其他活字更难,因为它很常见的短字符串优化:不是几个指针操作可能需要传输的字节。然而,实际上复制短字符串或指针实际上只是一个memcpy()潜在的操作,表明移动操作的源不再包含需要释放的字符串。

因此,简单的规则是

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