3

In this question about copy-and-swap, there is a swap() function in the accepted answer.

friend void swap(dumb_array& first, dumb_array& second) // nothrow
 {
    // enable ADL (not necessary in our case, but good practice)
    using std::swap; 

    // by swapping the members of two classes,
    // the two classes are effectively swapped
    swap(first.mSize, second.mSize); 
    swap(first.mArray, second.mArray);
}

Why not just std::swap(first, second)?

Community
  • 1
  • 1
ZHOU
  • 1,151
  • 2
  • 12
  • 27

2 Answers2

8

std::swap relies on the assignment operator. So if the assignment operator were to call std::swap, this would lead to an infinite chain of calls back and forth between the assignment operator and std::swap.

Regarding the question in your title. Yes, for a well-behaved class with value semantics, it is safe to call std::swap on objects of that class. Only the implementer of the class cannot use it for the copy-and-swap idiom for the reason stated above.

Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
  • `std::swap` does do a copy of both sides. Manual member-wise swap only copies 1 extra member at a time at worst, and on a `std::vector` does no copies at all (of the vector's data). – Yakk - Adam Nevraumont Apr 15 '15 at 11:42
1

The code snippet is suggested for C++98, there is another suggestion for C++11 (move semantics) in the same answer.

The reason why there is swap() function for C++98 solution is very well explained in Scott Meyers' Effective C++ book.

Briefly;

  template<typename T>          // typical implementation of std::swap;
  void swap(T& a, T& b)         // swaps a's and b's values
  {
    T temp(a);
    a = b;
    b = temp;
  }

As long as your types support copying (via copy constructor and copy assignment operator), the default swap implementation will let objects of your types be swapped without your having to do any special work to support it.

However, the default swap implementation may not thrill you. It involves copying three objects: a to temp, b to a, and temp to b. For some types, none of these copies are really necessary. For such types, the default swap puts you on the fast track to the slow lane.

Foremost among such types are those consisting primarily of a pointer to another type that contains the real data. A common manifestation of this design approach is the "pimpl idiom"...

Alper
  • 12,860
  • 2
  • 31
  • 41