|Now that I think about it, a std::unique_pointer wouldn't have much overhead.|
Their nature allows them not to have any sort of overhead (neither in run time, nor binary size nor memory usage). However, it's different for other smart pointer types, e.g. shared_ptr.
|However, I've never heard of a move constructor, that sounds very interesting!|
They were introduced in C++11. I recommend googling for "c++11 move semantics".
|What is a local object, is that an object on the stack inside the block that the return statement is in?|
Yes (or any block inside the function).
|Does this mean that a copy is merely simulated for returning something on the stack? |
Not really. Take this example:
Now one of several things can happen (3 being the most likely here):
1) the compiler is not able to perform copy/move elision. Then ret is moved into the return value and the return value is moved into vec.
2) the compiler is able to apply (N)RVO. Then ret is constructed directly into the return value of foo, which is then moved into vec.
3) the compiler is able to perform copy/move elision in both cases. Then ret in foo() is constructed directly into vec in main(). No copies or moves happen.
4) if vector<string> didn't have a move constructor (it does though, unless you're compiling in C++98 mode), then a copy would be performed instead of a move in the above cases.
Moves are intended to be very fast operations. In the case of a vector, it would move its internal pointer to the actual data when moved into another vector (well, technically it's the other vector that rips the pointer from the vector that is to be moved).
More stuff to read: