vendredi 11 août 2017

When to provide custom swap function in C++?

Consider a custom class X holding some resource (for simplicity represented here by an integer member variable) with move constructor (MC), move assignment operator (MAO), and a custom swap function:

class X {
  int i_;
public:
  X(int i) : i_(i) { }
  X(X&& rhs) = default; // move constructor 
  X& operator=(X&& rhs) = default; // move assignment operator 
  // X& operator=(X rhs) { std::swap(i_, rhs.i_); } // unifying assign. op.
  friend void swap(X& lhs, X& rhs) { std::swap(lhs.i_, rhs.i_); }
  int i() const { return i_; }
};

In the following benchmark code:

int main() {
  int i1, i2;
  std::cin >> i1 >> i2;

  X x1(i1), x2(i2);
  std::cout << x1.i() << x2.i();

  swap(x1, x2);
  std::cout << x1.i() << x2.i();

  std::swap(x1, x2);
  std::cout << x1.i() << x2.i();
}

  1. swap(x1, x2) simply swaps 2 integers.
  2. std::swap(x1, x2) calls 1x MC and 2x MAO.
  3. If MAO is substituted by unifying assignment operator (UAO), std::swap(x1, x2) calls 3x MC and 2x UAO.

(Tested with gcc/libstdc++).

Seemingly, custom swap is very valuable since it avoids many function calls. However, when I look at dissassemled output of this program: http://ift.tt/2uxgWSM, all the functionality of MC, MAO, UAO, swap and std::swap is inlined directly into main (gcc/clang with -O2 flag). Moreover, no object of type X is created in the program, it works only with integers at the machine code level.

Therefore, it seems to me that there is no reason to provide custom swap function for a class like X.

QUESTIONS:

  1. Is it good practice to assume that a compiler will optimize out calls of MC and MAO/UAO inside std::swap? Or, should I rather define custom swap for all custom classes?
  2. For what kinds of classes is custom swap really beneficial?

Aucun commentaire:

Enregistrer un commentaire