Why do some people use swap for move assignments?

后端 未结 4 702
一个人的身影
一个人的身影 2020-11-28 19:53

For example, stdlibc++ has the following:

unique_lock& operator=(unique_lock&& __u)
{
    if(_M_owns)
        unlock();
    unique_lock(std::move         


        
4条回答
  •  我在风中等你
    2020-11-28 20:25

    Another thing to consider regarding the trade-off:

    The default-construct + swap implementation may appear slower, but -sometimes- data flow analysis in the compiler can eliminate some pointless assignments and end up very similar to handwritten code. This works only for types without "clever" value semantics. As an example,

     struct Dummy
     {
         Dummy(): x(0), y(0) {} // suppose we require default 0 on these
         Dummy(Dummy&& other): x(0), y(0)
         {
             swap(other);             
         }
    
         void swap(Dummy& other)
         {
             std::swap(x, other.x);
             std::swap(y, other.y);
             text.swap(other.text);
         }
    
         int x, y;
         std::string text;
     }
    

    generated code in move ctor without optimization:

     
     x = 0;
     y = 0;
     temp = x;
     x = other.x;
     other.x = temp;
     temp = y;
     y = other.y;
     other.y = temp;
     
    

    This looks awful, but data flow analysis can determine it is equivalent to the code:

     x = other.x;
     other.x = 0;
     y = other.y;
     other.y = 0;
     text with other.text, set other.text to default>
    

    Maybe in practice compilers won't always produce the optimal version. Might want to experiment with it and take a glance at the assembly.

    There are also cases when swapping is better than assigning because of "clever" value semantics, for example if one of the members in the class is a std::shared_ptr. No reason a move constructor should mess with the atomic refcounter.

提交回复
热议问题