I tested the following code using Visual Studio 2017 version 15.3.1.
v.push_back(std::move(str1))
works as expected. It moves the contents of str1
into the vector.
str2
is a constant string. Since a constant string cannot be modified after it is created, I was expecting that the v.push_back(std::move(str2))
statement would result in a compiler warning. However, to my surprise there was no compiler warning. After stepped into it, I found that the overload of push_back(const T&)
was actually called. The std::move
in std::move(str2)
seems has no effect.
My question: Should a compiler warning be given for trying to move a constant object?
// Compiled with Visual Studio 2017 version 15.3.1
std::vector<std::string> v;
std::string str1 = "string 1";
v.push_back(std::move(str1));
// Call push_back(T&&). The contents of str1 is moved into the vector.
// This is less expensive, but str1 is now valid but unspecified.
const std::string str2 = "string 2";
v.push_back(std::move(str2));
// Call push_back(const T&). A copy of str2 is added into the vector.
// str2 itself is unchanged.
A move constructor requires the modification of the original object and since that object is const you cannot move so it calls the copy constructor instead.
std::move is totally unnecessary when returning from a function, and really gets into the realm of you -- the programmer -- trying to babysit things that you should leave to the compiler.
std::move is actually just a request to move and if the type of the object has not a move constructor/assign-operator defined or generated the move operation will fall back to a copy.
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.
No. Remember, std::move
doesn't move anything, it is a glorified cast through remove_reference_t
. Since in your case it is casted to const rvalue reference (as std::remove_reference_t<const T>
is const T
), it doesn't bind to rvalue reference overload push_back(T&& )
, and instead binds to const lvalue reference one - push_back(const T& )
.
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