As I understand copy-and-swap idiom, it has a drawback of needing of bolierplate code. Consider a simple "just-hold-all-those-damn-lemons" struct:
struct MuchData {
private:
std::string one, two;
int three;
std::vector<Something> four;
MyType five;
MyOtherType six, seven;
unsigned long long int still_overflows;
public:
MuchData() : one("."), two("/"), three(0), four(), five(), six(-1), seven(0), still_overflows(0)
{ }
MuchData(const MuchData& rhs) : one(rhs.one), two(rhs.two), three(rhs.three), four(rhs.four), five(rhs.five), six(rhs.six), seven(rhs.seven), still_overflows(rhs.still_overflows)
{ }
MuchData(MushData&& old) : one("."), two("/"), three(0), four(), five(), six(-1), seven(0), still_overflows(0)
{ swap(*this, old); }
MuchData& operator=(MuchData old) { swap(*old, this); return *this; }
friend void swap(MuchData& left, MushData&right) {
using std::swap;
swap(left.one, right.one);
swap(left.two, right.two);
swap(left.three, right.three);
swap(left.four, right.four);
swap(left.five, right.five);
swap(left.six, right.six);
swap(left.seven, right.seven);
swap(left.still_overflows, right.still_overflows);
}
// And now we can go and do something interesting
};
With initializers written in
: one(".")
, two("/")
, three(0)
// etc.
style, this code takes even more space. And MyType
and MyOtherType
are probably defined with this technique as well... is there any way to reduce the amount of repetitiveness here? When new fields are added, for example, it's extremely easy to forget to add the corresponding swap(...)
line, which causes a mysterious slicing.