First, std::move does not move, and std::forward not forwarded.
std::move is a link to the rvalue link. By convention, rvalue links are considered to be โlinks to which you are allowed to transfer data, since the caller promises they no longer need this data.โ
On the other hand of the fence, rvalue links are implicitly bound to the return value of std::move (and sometimes are forwarded), to temporary objects, in some cases when returning local from a function and when using a member, a temporary or moved object.
What happens inside a function using an rvalue reference is not magic. It cannot require storage directly inside the object in question. However, he can tear out his guts; he has permission (by convention) to mess with his internal state of the arguments if he can make the operation faster this way.
Now C ++ will automatically write some move constructors for you.
struct MyStruct { int iInteger; string strString; };
In this case, he will write something that looks something like this:
MyStruct::MyStruct( MyStruct&& other ) noexcept(true) : iInteger( std::move(other.iInteger) ), strString( std::move(other.strString) ) {}
That is, it will create an elemental displacement construct.
When you move an integer, nothing interesting happens. There is no benefit in being involved in the original integer state.
When you move std::string , we get some efficiency. The C ++ standard describes what happens when you go from one std::string to another. Basically, if the source std::string uses a heap, the heap storage is transferred to the destination std::string .
This is a common C ++ container template; when you move from them, they steal the "storage heaped" source container and reuse it at the destination.
Note that the source of std::string remains std::string , only the one that has "dropped guts". Most containers like things have remained empty, I donโt remember if std::string makes this guarantee (maybe not because of SBO), and now it doesnโt matter.
In short, when you switch from something, its memory is not "reused", but the memory that it has can be reused.
In your case, MyStruct has std::string , which can use the allocated memory heap. This memory allocated by the heap can be transferred to MyStruct stored in std::vector .
Going a little down the rabbit hole, "Hello" is likely to be so short that SBO will happen (slight buffer optimization), and std::string does not use heaps at all. In this particular case, there can be no performance improvement due to move ing.