Skip to content

Instantly share code, notes, and snippets.

@Veedrac
Last active March 1, 2016 11:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Veedrac/978c91238ac681323524 to your computer and use it in GitHub Desktop.
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.
};
@Veedrac
Copy link
Author

Veedrac commented Jun 15, 2015

Advantages?

  • No need for swap, which makes it IMHO simpler logistically.
  • Moves aren't implemented as three moves, as swap(*this, other)
    would imply.
  • Copy assignment is simpler.
  • Moves don't have to be a swap, which might be more convenient.

@Veedrac
Copy link
Author

Veedrac commented Mar 1, 2016

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment