I would like to move an object into a std::vector using std::vector::push_back(). This would seem to be possible since there is a std::vector::push_back(value_type&& val) function. But due to the the existence of std::vector::push_back(value_type const & val), which copies and would be the overriding call, I need to convert the lvalue object to an rvalue.
How is this done?
Example:
struct X { int x; X(int x) : x(x) {} };
int main()
{
std::vector<X> ax;
X x(3);
ax.push_back(x); // <= Want to move x in to vector ax, not copy.
return 0;
}
Actually, maybe it can't be? I ask this because after writing this example, my new questions are:
x into ax, what is the value of x.x? If X had an explicit destructor, what would happen to x when it leaves scope?Just use std::move():
ax.push_back(std::move(x));
Concerning your question:
If I do move x into ax, what is the value of x.x?
In this case, your class X does not contain an explicitly declared move constructor, so the compiler will generate one that does memberwise move of X's members. Since X only has one member of type int, and moving an int is no different from copying it, then x.x will have the same value it had before being moved from.
If X had an explicit destructor, what would happen to x when it leaves scope?
If X has a user-declared destructor, that will inhibit the generation of an implicit move constructor - but not that of an implicit copy constructor. Therefore, this function call:
ax.push_back(std::move(x));
Will result in x being copied into ax. In any case, x will be destroyed when going out of scope, since it has automatic storage duration - no matter whether a user-declared destructor is present or not.
In general, one should not make assumptions on the state of an object that has been moved from, except that that state is valid (paragraph 17.6.5.15/1 of the C++11 Standard guarantees this to be the case for types of the Standard Library).
In concrete, this means that the only functions that can safely work with an object that has been moved from are those that do not have any precondition on the state of that object. Typically, two such functions are the destructor and the (copy- or move-) assignment operator.
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