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