The Copy-and-Swap idiom is obsolete?

I still see people using the Copy-And-Swap idiom! It was made popular by the Scott Meyers book “Effective C++” which is one of the most read C++ books. However, the third edition was released in 2011, before C++ 11 took hold. Since C++11 however, we have move operators and constructors, and the Copy-And-Swap idiom has ever since become obsolete.

Why is it obsolete? Because this code will not compile:


struct Foo {

  int x;

  Foo &operator=(Foo other) // copy
  {
    swap(other); // and swap
    return *this;
  }

  Foo &operator=(Foo &&other) noexcept {
    x = other.x;
    other.x = 0;
    return *this;
  }

}


{
  Foo A, B;
  A = std::move(B);
}

When you convert B into an rvalue, it will bind to both functions (copy and move), and the compiler will complain that multiple operator= match this operand.
In simpler terms “Foo&&” binds equally to both “Foo&&” and “Foo” because of reference collapsing, thus the ambiguity.

Well, in reality as it turns out, the copy-and-swap idiom isn’t strictly defined where Foo is passed by value, so my article headline is a bit misleading. Passing it by const ref and then performing a copy and swap within the function itself is still considered part of the idiom, and that’s not obsolete at all!

So you should simply write a normal copy assignment operator (same goes for constructors) such as:

Foo& operator= (const Foo& other);

Leave a Reply

Your email address will not be published. Required fields are marked *