Which to use: move assignment operator vs copy assignment operator

后端 未结 2 788
孤独总比滥情好
孤独总比滥情好 2021-02-08 18:14

I don\'t seem to get why would you use the move assignment operator:

CLASSA & operator=(CLASSA && other); //move assignment operator
         


        
2条回答
  •  迷失自我
    2021-02-08 18:58

    Clearly, the two overloads are not equivalent:

    1. The assignment operator taking an rvalue reference only works with rvalues are on the right-hand side of the expression. To also support lvalues, another overload, e.g., using T const& would be needed for copyable types. Of course, for move-only types, like std::unique_ptr, defining this assignment operator is the appropriate choice.
    2. The assignment operator taking a value covers both rvalue and lvalue assignments assuming the type in question is both copy- and move-constructible. Its canonical implementation is to call swap() to replace the object's state with the state from the right-hand side. It has the advantage that the copy/move construction of the argument can often be elided.

    In any case, you wouldn't want to have both overloads in one class! When assigning from an lvalue, obviously, the version taking a value would be chosen (the other option isn't viable). However, both assignment operators are viable when assigning an rvalue, i.e., there would be an ambiguity. This can easily be verified by trying to compile this code:

    struct foo
    {
        void operator=(foo&&) {}
        void operator=(foo) {}
    };
    
    int main()
    {
        foo f;
        f = foo();
    }
    

    To deal with a move- and copy construction separately you could define a pair of assignment operators using T&& and T const& as arguments. However, this results in having to implement two versions of essentially the same copy assignment while having just a T as argument requires just one copy assignment to be implemented.

    Thus, there are two obvious choices:

    1. For a move-only type you'd define T::operator= (T&&).
    2. For a copyable type you'd define T::operator=(T).

提交回复
热议问题