camino camino - 3 months ago 17
C++ Question

Why can we use `std::move` on a `const` object?

In C++11, we can write this code:

struct Cat {

const Cat cat;
std::move(cat); //this is valid in C++11

when I call
, it means I want to move the object, i.e. I will change the object. To move a
object is unreasonable, so why does
not restrict this behaviour? It will be a trap in the future, right?

Here trap means as Brandon mentioned in the comment:

" I think he means it "traps" him sneaky sneaky because if he doesn't
realize, he ends up with a copy which is not what he intended."

In the book 'Effective Modern C++' by Scott Meyers, he gives an example:

class Annotation {
explicit Annotation(const std::string text)
: value(std::move(text)) //here we want to call string(string&&),
//but because text is const,
//the return type of std::move(text) is const std::string&&
//so we actually called string(const string&)
//it is a bug which is very hard to find out
std::string value;

was forbidden from operating on a
object, we could easily find out the bug, right?

struct strange {
  mutable size_t count = 0;
  strange( strange const&& o ):count(o.count) { o.count = 0; }

const strange s;
strange s2 = std::move(s);

here we see a use of std::move on a T const. It returns a T const&&. We have a move constructor for strange that takes exactly this type.

And it is called.

Now, it is true that this strange type is more rare than the bugs your proposal would fix.

But, on the other hand, the existing std::move works better in generic code, where you don't know if the type you are working with is a T or a T const.