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)
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.
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.
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.
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.
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:
std::move(arg)
).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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With