編集
Scott Meyer の記事を参照してください。私の回答の確認については、Effective C++ 3rd Editionの項目 25: 非スロー スワップのサポートを検討してください (p106-p112)を参照してください。
元の答え
Scott Meyers がこれについて書いているので、私の答えは記憶から来ています。
まず、クラスの名前空間で swap 関数を定義します。例えば :
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 で swap 関数を特殊化します。例えば :
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 (**)
// }
}
swap 関数を使用する場合は、std swap 関数をスコープにインポートして間接的に行います。例えば :
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 関数を呼び出すのが良いパターンです。