Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to use std::move for strings?

Tags:

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_;
};

My technique was always using

constructor(const std::string& argument): field(argument)
like image 419
ar2015 Avatar asked Dec 16 '17 01:12

ar2015


People also ask

When should we use std :: move?

std::move is used to indicate that an object t may be "moved from", i.e. allowing the efficient transfer of resources from t to another object.

How do you move a string in C++?

std::move in C++ Moves the elements in the range [first,last] into the range beginning at result. The value of the elements in the [first,last] is transferred to the elements pointed by result. After the call, the elements in the range [first,last] are left in an unspecified but valid state.

Where is std :: move defined?

std::move() is a function used to convert an lvalue reference into the rvalue reference. Used to move the resources from a source object i.e. for efficient transfer of resources from one object to another. std::move() is defined in the <utility> header.

Why do we need STD moves?

std::move can also be useful when sorting an array of elements. Many sorting algorithms (such as selection sort and bubble sort) work by swapping pairs of elements. Previously, we've had to resort to copy-semantics to do the swapping. Now we can use move semantics, which is more efficient.


1 Answers

The idiom of accepting parameters by value makes sense when the value of a movable type is consumed. With consuming a value I mean that the value is forward to something which requires its own copy of the value. The reason here is this:

  • When an argument is passed by value a copy can be elided, e.g., when the argument is the result of a different function call. Even when the copy can't be elided, the argument can potentially be made to look like a temporary (e.g., using std::move(arg)).
  • Since a value is passed into the function, i.e., the function already owns a copy, this value can forwarded wherever it is needed.
  • In the worst case the argument gets copied but since a value is needed anyway a copy would need to be created from a T const& parameter, too, and the additional move operation is assumed to be comparatively cheap.

Thus, the expectation is that in the worst case there may be small additional work but in the normal case there is substantially less work as only one move operation instead of a copy is done.

For std::string the argument is slightly harder than for other movable types due to its quite common short string optimization: instead of a few pointer operations there may be a need to transfer bytes. However, in practice copying the short string or the pointers is effectively just a memcpy() potentially followed by an operation indicating that the source of the move operation no longer contains a string which needs be released.

Thus, the simple rule is

When consuming a movable object accept the argument by value and move the object rather than pass the argument via a T const& and create a copy to consume the result.

like image 112
Dietmar Kühl Avatar answered Oct 17 '22 18:10

Dietmar Kühl