Which copy/move constructor/operator to define for simple structures?

assignment-operator, c++, c++11, copy-constructor, move-semantics

Solution

Q1: Can you rely on the compiler to auto-generate those?

Yes (in your example). See the C++11 Standard (clause 12), or the article Implicit Move Won’t Go! (nice diagram near the end). To sum up (and simplify), all the following special member functions will be auto-generated (implicitly declared and defined as defaulted):

- Destructor – because you didn't declare it.

- Copy Constructor – because you didn't declare it nor any of MC and MAO.

- Copy Assignment Operator – because you didn't declare it nor any of MC and MAO.

- Move Constructor – because you didn't declare it nor any of D, CC, CAO and MAO.

- Move Assignment Operator – because you didn't declare it nor any of D, CC, CAO and MC.

(I used ugly initials only to keep the list items one line each.) In addition to the "because"s above, for all but the Destructor there's the additional constraint that the generated defaults must make sense, i.e. all the data members must be copyable (for the CC and CAO) or movable (for the MC and MAO). (Actually the precise rules are a bit more complicated, but I don't want to rephrase the Standard here.)

Q2: Are the auto-generated functions correct?

Yes (in your example). All your data members (here plain `int`s) have correct copy/move semantics (their copy/move constructors and assignment operators do the right thing, and those auto-generated for `Rect` will call them).

Q3: Anyway, should you define them manually?

I see no advantage to it (in your example), and potential issues (as in your example, see comments).

Problem

My program uses a simple structure `Rect` which is defined as ``` struct Rect { int x1, y1, x2, y2; Rect() : x1(0), y1(0), x2(0), y2(0) { } Rect(int x1, int y1, int x2, int y2) : x1(x1), y1(y1), x2(x2), y2(y2) { } }; ``` Should I define a copy/move constructor or an assignment operator, or can I rely on the compiler to auto-generate those? The question is in context of speed and usage reasons (eg. a move constructor can influence program execution speed). The constructors and operator are very repetitive work, so it'll be nice if I can rely on the compiler to generate them automatically. ``` Rect(const Rect& r) : x1(r.x1), y1(r.y1), x2(r.x2), y2(r.y2) { } Rect(Rect&& r) : x1(r.x1), y1(r.y1), x2(r.x2), y2(r.y2) { } Rect& operator = (const Rect& r) { x1 = r.x1; y1 = r.y1; x2 = r.x2; y2 = r.y2; } ```

Original source