Search code examples
c++c++11copy-assignmentmove-assignment-operator

Compiler won't use copy assignment instead move?


I have a class where the move assignment is explicit deleted, since the object should not be moveable. But if i assign to an instance of this class using RVO the compiler gives me the error:

main.cpp:12:16: note: candidate function has been explicitly deleted

also the compiler is mentioning the existing copy assignment operator but does not use it.

here is my code (or a (not) running example here):

class foo {
public:
    foo() {}
    foo(foo const& r) {}
    foo(foo&&) = delete;

    foo const& operator=(foo const& r) { return *this; }
    foo const& operator=(foo&& r) = delete;
};

int main(int argc, char **argv) {
    foo bar;
    bar = foo();
    return 0;
}

I found a quite similar post here.

I know I can avoid this by using a temporary. i wonder why every compiler (i tested this with gcc, clang and vs2013) is not able to call the existing copy assignment directly? Is there something I am missing?


Solution

  • The copy assignment is not called, because the (deleted) move assignment is a better match for overload resolution.

    Simply don't declare the move assignment at all. Then the copy assignment will be selected. The implicit move assignment operator won't be generated because the class has a user declared copy constructor, move constructor and copy assignment operator. Any of those will prevent the generation of the implicit move assignment operator.


    But if i assign to an instance of this class using RVO

    There is no RVO involved here. You create a temporary foo and copy assign it to an existing variable. Copy assignments cannot be elided.

    Also, it's quite unusual and inefficient to return by value from an assignment operator.