Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move constant object without compiler warning

Tags:

c++

c++11

c++17

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.
like image 649
Garland Avatar asked Aug 21 '17 19:08

Garland


People also ask

Can a const object be moved?

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.

Do I need to return std :: move?

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.

Does STD copy move?

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.

What does std :: move () do?

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.


1 Answers

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& ).

like image 93
SergeyA Avatar answered Sep 19 '22 13:09

SergeyA