0

I c++ programming language 13.6.2 std::swap is used to implement move semantics the idea is below:

class deutscheSchweine{
 public:
  deutscheSchweine(){std::cout<<"DS\n";}
  deutscheSchweine& operator=(const deutscheSchweine& other){
   deutscheSchweine tmp;
   swap(*this, tmp);
   return *this;
  }
  deutscheSchweine(deutscheSchweine&& other){}
  deutscheSchweine& operator=(deutscheSchweine&& other){
   swap(*this, other);
   return *this;
  }
};


int main(){
deutscheSchweine ds;
deutscheSchweine ds2;
ds2 = ds;

I above example after calling assignment we can use move semantics to avid copying from temporary, but this example causes recursively calling move assignment. My question is can we use swap in move semantics but in some proper way?

T.C.
  • 123,516
  • 14
  • 264
  • 384
Mateusz Wojtczak
  • 1,503
  • 9
  • 25
  • If you want to implement move assignment in terms of swap, it needs to be your own swap, not the default one, which is implemented in terms of move assignment (and move construction), and would result in turtles all the way down... – T.C. Nov 29 '15 at 10:31
  • Thank that is the correct answer to my question, as probably this detail wasn't mentioned when swap was used with move assignment in book. – Mateusz Wojtczak Nov 29 '15 at 11:18
  • 1
    Is deutscheSchweine meant as offensive or agrarian term? – Sebastian Jun 05 '20 at 06:58

1 Answers1

0

Implementing copy-assignment via swap is a good idea, but you missed some of the details.

You need to call move on each of the individual members at some point. That can be done by calling swap(*this, other); and implementing a specialization of swap, by directly calling swap on each of the individual members, or by letting std::swap call your move assignment operator.

Move assignment should NOT be implemented using swap.

We already have an excellent guide to the "copy-and-swap" idiom, here: What is the copy-and-swap idiom?

Also read Should the Copy-and-Swap Idiom become the Copy-and-Move Idiom in C++11?

In the end, what you want (assuming your member objects are designed correctly) is:

class deutscheSchweine
{
 public:
  deutscheSchweine(){std::cout<<"DS\n";}

  // defaulted move operations (member-wise moves)
  deutscheSchweine(deutscheSchweine&& other) = default;
  deutscheSchweine& operator=(deutscheSchweine&& other) = default;

  // copy construction is defaulted (member-wise copies)
  deutscheSchweine(const deutscheSchweine& other) = default;

  // copy assignment uses copy-and-move for exception safety
  deutscheSchweine& operator=(deutscheSchweine other)
  {
    return *this = std::move(other);
  }
};
Community
  • 1
  • 1
Ben Voigt
  • 260,885
  • 36
  • 380
  • 671
  • 1
    Um, that will be ambiguous at overload resolution. There's no tiebreaker for `T` vs `T&&`. – T.C. Nov 29 '15 at 10:28
  • 1
    `deutscheSchweine(deutscheSchweine other) = default;` is not a valid constructor signature – M.M Nov 29 '15 at 10:33