I fail to understand the real nature std::move
std::move(object)
returns "an Rvalue reference to that object". Yes, I got this.push_back(std::move(object))
instead of push_back(object)
to avoid copying. I didn't get this, because it seems to contradict with the example below:#include <utility>
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
template <class T> void print(T const & object){
for (auto var : object){std::cout << ' '<<var;}
std::cout << '\n';
}
int main () {
std::string foo = "foo-string";
std::string bar = "bar-string";
std::vector<std::string> myvector = { "super", "vip" , "pro" , "ok" }; // capcity=size=4;
// this block is just to increase the capacity of the vector
myvector.push_back( "rango" ); //NOW: capacity = 8 , size =5
std::cout << &myvector[0] <<'\n'; //check the address of the first element of the vector
// this block is the point of the problem
myvector.push_back(foo); // copies -> YES!
myvector.push_back(std::move(bar)); // moves !?!?
std::cout << "myvector contains:";
print(myvector);
std::cout << &myvector[0] << '\n'; // re-check the address of first element of the vector = still the same.
std::cout << "the moved-from object: " << std::quoted(bar);
return 0;
}
push_back(std::move(object))
is the same, meaning the address of the last element
by push_back
must be stored at "a fixed distance" from the first element (in this case)Let's break down what a move actually means in C++
std::vector
for example has a dynamically allocated buffer where it stores its elements. So when you move construct a std::vector
from another std::vector
the newly created object will take over (or steal if you will) the buffer from the old object. It will still be a new object though and have distinct memory location.In the case of std::string
things get a little more complicated. Conceptually std::string
is very similar to std::vector<char>
but it has what is called a small buffer optimization (in common implementations at least). This means, that if the string is under a certain length, it will be stored within the std::string
object, not in a dynamically allocated buffer. Usually the threshold is around 20 characters. Only larger strings will be placed on the free store. Because your string "bar-string"
is fairly short, it will be placed within the std::string
object and thus a move results in a copy of the string.