why should we define a specialization std::swap?

according to item 25 in effective C++ 3rd. we should define a nonmember swap in the same namespace as our own class or template. but it says we still need to specialize std::swap for it.
we can always call the one in the same namespace as our class through ADL, so why should we specialize std::swap? is it necessary?
> but it says we still need to specialize std::swap for it.

It does not say we need to specialize std::swap

The recommended way to make a user-defined type swappable with a custom swap is to provide a non-throwing non-member function swap in the same namespace as the type.

The standard specifies in 'Library-wide requirements':
The context in which swap( t, u ) and swap( u, t ) are evaluated shall ensure that a binary non-member function named “swap” is selected via overload resolution on a candidate set that includes:
— the two swap function templates defined in <utility> and
— the lookup set produced by argument-dependent lookup.


That is, the library components are required to call unqualified swap():
any time the standard library performs a swap, it uses the equivalent of using std::swap; swap( t, u );.
Typical implementations either
1) Define a non-member swap in the enclosing namespace, which may forward to a member swap if access to non-public data members is required
2) Define a friend function in-class (this approach hides the class-specific swap from name lookup other than ADL)
http://en.cppreference.com/w/cpp/concept/Swappable


Scott Meyers' point is this:

1. The right way to call swap from user code for a generic type is: using std::swap; swap( t, u );

2. However, some (misguided, as Meyers mentions) programmers may call qualified std::swap() instead.
std::swap( t, u ); would force the compiler to consider only the swap in namespace std
(ie. not look for the swap in the same namespace as the type involved).

3. To protect against this error, it is a good idea to specialize std::swap for the user-defined type.
(In addition to the non-throwing non-member function swap in the same namespace as the type.)
thanks for your answering. but i still have a little question. if we specialize std::swap, and have using std::swap; before swap(t, u);, why does this swap call the swap defined in the same namespace as the type? using declaration introduce std::swap to the same scope as swap(t, u), why not call the std::swap? does it mean ADL have priority over normal name lookup?
Last edited on
does it mean ADL have priority over normal name lookup?
No, but by overload resolution rules non-templated functions are preferred.

Selecting a function overload is done in two stages: first all viable overloads are selected (This is where ADL woks), second stage is selection of most viable one (if there is several such functions, you will get ambiguity error).
thank you very much!
Topic archived. No new replies allowed.