Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it portable to self move a std::string?

Tags:

c++

c++20

std::string s = "y";
s = "x" + std::move(s) + "x";
Send(std::move(s));

Microsoft STL implementation checks for this, but is it mandated by the standard?

It looks more clean than insert + append or two variables approach.

Note: I know I can do Send(std::move("x" + std::move(s) + "x")), but real code is not so simple.

like image 318
OwnageIsMagic Avatar asked Sep 30 '21 15:09

OwnageIsMagic


People also ask

Is std::string movable?

Yes, std::string (since C++11) is able to be moved i.e. it supports move semantics.

Does std :: move do anything?

std::move itself does "nothing" - it has zero side effects. It just signals to the compiler that the programmer doesn't care what happens to that object any more. i.e. it gives permission to other parts of the software to move from the object, but it doesn't require that it be moved.

What happens when you to 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. In particular, std::move produces an xvalue expression that identifies its argument t . It is exactly equivalent to a static_cast to an rvalue reference type.


1 Answers

There's no self-move here. A self-move is something like this:

s = std::move(s);

which means

s.operator=(std::move(s));

In other words, when operator= is called, this points to the same string as the argument.

In your code, "x" + std::move(s) will be evaluated first, which returns a std::string prvalue. In other words, not a reference to s, although it's possible that the concatenation might "steal" the buffer from s. Then the second + is evaluated, and another prvalue is returned. Finally, operator= is called. At this point, the prvalue on the right-hand side has to be materialized, because it's bound to the rvalue reference argument of operator=. So all we have is s being assigned from a temporary object, which might have stolen s's buffer. But no matter: s is an object of a standard library type, which means that it is in a "valid but unspecified state". Since s is in a valid state, and is not the same object as the RHS, there is no problem.

like image 120
Brian Bi Avatar answered Oct 23 '22 12:10

Brian Bi