Edit
See Scott Meyer's article: See Effective C++ 3rd Edition, item 25: Consider support for a non-throwing swap (p106-p112) for a confirmation of my answer.
Original answer
Scott Meyers wrote about this, so my answer comes from memory.
First, define a swap function in the namespace of your class. For example :
namespace MyNamespace
{
class MyClass { /* etc. */ } ;
template<typename T>
class MyTemplate { /* etc. */ } ;
void swap(MyClass & lhs, MyClass & rhs)
{
// the swapping code (**)
}
template<typename T>
void swap(MyTemplate<T> & lhs, MyTemplate<T> & rhs)
{
// the swapping code (**)
}
}
Then, if possible (it is not always possible for templated classes (*) ), specialize the swap function in the namespace std. For example :
namespace std
{
template<>
void swap<MyNamespace::MyClass>(MyNamespace::MyClass & lhs, MyNamespace::MyClass & rhs)
{
// the swapping code (**)
}
// The similar code for MyTemplate is forbidden, so don't try
// to uncomment it
//
// template<typename T>
// void swap<MyNamespace::MyTemplate<T> >(MyNamespace::MyTemplate<T> & lhs, MyNamespace::MyTemplate<T> & rhs)
// {
// // the swapping code (**)
// }
}
The, when using the swap function, do it indirectly, importing the std swap function into your scope. For example :
void doSomething(MyClass & lhs, MyClass & rhs)
{
// etc.
// I swap the two objects below:
{
using std::swap ;
swap(lhs, rhs) ;
}
// etc.
}
void doSomethingElse(MyTemplate<int> & lhs, MyTemplate<int> & rhs)
{
// etc.
// I swap the two objects below:
{
using std::swap ;
swap(lhs, rhs) ;
}
// etc.
}
As soon as I have access to my books, I'll post here the exact reference.
- (*) template partial specialization of a function is forbidden
- (**) of course, a good pattern is to have a "swap" method declared in the class, have the swap functions call the swap method, and have the user call the swap function.