Редактировать
См. Статью Скотта Мейера: См. Эффективное C ++, 3-е издание , пункт 25. Рассмотрите возможность поддержки безброскового свопа (p106-p112) для подтверждения моего ответа.
Оригинальный ответ
Скотт Мейерс писал об этом, поэтому мой ответ приходит из памяти.
Сначала определите функцию подкачки в пространстве имен вашего класса. Например:
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 (**)
}
}
Затем, , если возможно (это не всегда возможно для шаблонных классов (*)), специализировать функцию подкачки в пространстве имен std. Например:
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 (**)
// }
}
При использовании функции подкачки сделайте это косвенно, импортировав функцию подкачки std в вашу область видимости. Например:
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.
}
Как только у меня будет доступ к моим книгам, я опубликую здесь точную ссылку.
- (*) шаблон частичной специализации функции запрещен
- (**), конечно, хорошим примером является метод «swap», объявленный в классе, функции swap, вызывающие метод swap, и пользователь, вызывающий функцию swap.