-
-
Save Veedrac/978c91238ac681323524 to your computer and use it in GitHub Desktop.
#include <algorithm> | |
class X { | |
private: | |
std::size_t size; | |
int *data; | |
public: | |
// You still keep the main three, the constructor, | |
// copy constructor and destructor, | |
X(std::size_t size = 0): | |
size(size), data(new int[size]()) {} | |
X(X const &other): X(other.size) { | |
std::copy(other.data, other.data + size, data); | |
} | |
virtual ~X() { delete[] data; } | |
// But instead of defining swap, you | |
// define a move assignment. | |
// Almost a swap, but it doesn't have to be. | |
X &operator=(X &&other) { | |
size = other.size; | |
std::swap(data, other.data); | |
return *this; | |
} | |
// The other implementations are just like | |
// copy-and-swap, except using moves instead. | |
X(X &&other): X() { *this = std::move(other); } | |
X &operator=(X const &other) { return *this = X{other}; } | |
// A swap is three moves, and implicit. | |
}; |
Strangely, looking at the assembly std::swap
is doing better when implicitly defined in copy-and-move than when explicitly written in copy-and-swap. Moves are also better, though the differences are one, one and two instructions (on top of 10, 10 and 7 respectively) for swaps, move construction and move assignment respectively.
Copy construction and assignment are also similar, but noticeably in favor of copy-and-swap. It turned out the difference stemmed solely from using int[size]()
instead of int[size]
, which value initializes the backing array (to 0). After this change was removed, the difference disappeared.
Overall, it appears that copy-and-move is both faster and easier to write than copy-and-swap, and so my suggestion is to strictly prefer the former.
Advantages?
swap(*this, other)
would imply.