Stack Exchange
How std::move copies noncopyable objects?
Consider the following code.
#include <iostream>
#include <type_traits>

struct A
{
    int x;
    A() = default;
    ~A() = default;

    A(const A&) = delete;
    A &operator=(const A&) = delete;

    A(A &&) = default;
    A &operator=(A &&a) = default;
};

int main()
{
    std::cout << std::boolalpha;
    std::cout << std::is_copy_constructible<A>::value << std::endl;
    std::cout << std::is_copy_assignable<A>::value << std::endl;

    A a;
    a.x = 3;

    A b = std::move(a);

    std::cout << std::hex << a << " " << &b << std::endl;
    std::cout << a.x << " " << b.x;

    return 0;
}

The example input is:
false
false
0xbfd1ee28 0xbfd1ee2c
3 3

As you can see, the variable b has been successfully copied although the class A is noncopyable by design. I totally understand that the variable a won't be moved anywhere. The std::move call should probably construct an rvalue-reference copying the object a first, but hey, isn't it forbidden in the class definition?
Can anybody explain, what is going on in here?

Is it just me, or moving isn't copying?

how is it forbidden when you explicitly asked for move here, remove std::move the code won't compile.

Why do you think there was a copy? You asked the compiler to generate a move constructor for you. The generated move constructor will do a memberwise move of all elements. There are basically two scenarios:

The corresponding member has a move constructor in which case this move constructor will be applied.
The corresponding member has no move constructor in which case the copy constructor will be applied.

Moving built-in types is like copying them, i.e., they don't do anything to source of the move unlike, e.g., std::unique_ptr<T> which will put a null-pointer into the source.
When you used
A b = std::move(a);

you give a the appearance of a temporary object which can be move constructed, using the generated move constructor for A. The rvalue-reference isn't constructed but the same object is simply cast. std::move(a) is equivalent to static_cast<A&&>(a).

Should we now discuss direct initialization (type var(init);) and move-initialization (type var = init;) instead of copy-initialization?

@BenVoigt: Well, type var = init; isn't quite as simple: if init is of type type it is copy-initialization. Only if init has a different type from type it is move-initialization (after a conversion). Of course, I prefer direct initialization in the first place and I would spell it type var{init};.

@DietmarKühl isnt it also illegal to access a moved from object, i.e a in the OP's case?

@Koushik: It is a reasonable guideline to assume that a moved from object is in an odd state and it probably shouldn't be accessed and the standard doesn't make any guarantees in general that it can be accessed. Specific classes can, however, choose to leave objects in a well-defined state and, e.g., the standard container classes are defined in a way which allows using the object although it doesn't mandate what state the containers are in. Likewise, A's move constructor actually guarantees that the moved from object is unchanged (moving ints is the same as copying them).

A b = a;

This wouldn't work because A is non-copyable. That is, because a is an lvalue expression, this will attempt to use the copy constructor which has been deleted, so it won't compile.
A b = std::move(a);

This will work because A is moveable. That is, because std::move(a) is an rvalue expression, this will attempt to use the move constructor which is defaulted, so it will compile.
Only in the first case is a copy attempted. The second does not involve a copy. Just because b ended up being constructed, doesn't mean it was copied from a. Instead, it has been moved from a.
