Search code examples
c++copy-constructorrvalue-referencemove-constructor

Why does the compiler choose the copy ctor after calling move



For the following code, I know that because I implement a copy constructor the default move is blocked by the compiler, what I don't understand is why the compiler choose the copy constructor, and not issuing an error?
Can a rvalue reference be the parameter for a reference function if no rvalue ref function exists?
If not, what do happens here?

#include <iostream>

using namespace std;

class A{
    public:

        A(){printf("constructor\n");}
        A(const A& a){printf("copy constructor");}
};

int main()
{ 
    A a;
    A b = std::move(a);
    return 1; 
}

The output is:

constructor
copy constructor

Thanks


Solution

  • The reason is that rvalue expressions can be bound to function parameters that are const lvalue references.


    Also note that const rvalue expressions cannot be bound to rvalue references:

    class A{
        public:    
            A(){printf("constructor\n");}
            A(const A& a){printf("copy constructor");}
            A(A&&) = default; // <-- has move ctor
    }; 
    
    int main()
    { 
        const A a; // <-- const!
        A b = std::move(a); // <-- copy not move!!!
        return 1; 
    }
    

    The code above still calls the copy constructor, even though there is a move constructor.