-1

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

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


int main(){
greenCars ds;
greenCars 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?

Catija
  • 359
  • 6
  • 21
Mateusz Wojtczak
  • 1,621
  • 1
  • 12
  • 28
  • 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 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 greenCars
{
 public:
  greenCars(){std::cout<<"DS\n";}

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

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

  // copy assignment uses copy-and-move for exception safety
  greenCars& operator=(greenCars other)
  {
    return *this = std::move(other);
  }
};
Catija
  • 359
  • 6
  • 21
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • 2
    Um, that will be ambiguous at overload resolution. There's no tiebreaker for `T` vs `T&&`. – T.C. Nov 29 '15 at 10:28