Why move on const objects work?

c++, c++11, move, move-semantics

Solution

You're not moving anything.

`std::move` is really poorly named: it doesn't force a move; it just returns an rvalue. It's up to the compiler to decide which constructor of `std::vector<int>` to invoke, and that's what determines whether you get a move.

If the container can't be moved because the target's move constructor isn't a match, then the copy constructor will be used instead, through basic overload rules.

#include <iostream>

struct T
{
    T() = default;
    T(const T&) { std::cout << "copy ctor\n"; }
    T(T&&)      { std::cout << "move ctor\n"; }
};

int main()
{
    T a;
    T b = std::move(a);   // "move ctor"

    const T c;
    T d = std::move(c);   // "copy ctor" - `const T&&` only matches copy ctor



    // (shut up GCC)
    (void) b;
    (void) d;
}

(live demo)

It's designed this way (`const T&&` being able to bind to `const T&`) at least in part because moving is intended to be best-effort, exactly so that you don't have to fight with compiler errors in cases like this.

Problem

I have a simple code : ``` const std::vector<int> data = {1,2,3}; std::vector<int> data_moved=std::move(data); for(auto& i:data) cout<<i;//output is 123 ``` It compiles without any errors or warning !! and It seems the `data` still has the values in it ! moving a const value doesn't seems correct because we can not modify const objects So how does that code compiles ?!

Original source