名前空間への宣言の追加は一般に未定義の動作であるため、(2)(ユーザー定義クラスが宣言されているのと同じ名前空間に自立swap
する)がswap
ユーザー定義クラスを提供する唯一の許可された方法のようstd
です。名前空間std(cppreference.com)の拡張:
以下に示すいくつかの例外を除いて、std
名前空間または内std
にネストされた名前空間に宣言または定義を追加することは未定義の動作です。
そしてswap
、それらの例外の1つとして示されていません。したがってswap
、std
名前空間に独自のオーバーロードを追加することは、未定義の動作です。
また、標準ライブラリは、ユーザー定義が提供されている場合、ユーザークラスのユーザーswap
定義を呼び出すために関数への非修飾呼び出しを使用するとも言われswap
ていますswap
。
交換可能(cppreference.com):
多くの標準ライブラリ関数(たとえば、多くのアルゴリズム)は、引数がSwappableを満たすことを期待しています。つまり、標準ライブラリがスワップを実行するときはいつでも、と同等のものを使用しusing std::swap; swap(t, u);
ます。
スワップ(www.cplusplus.com):
標準ライブラリ(内std
)の多くのコンポーネントは、この汎用バージョンの代わりに、非基本型のカスタムオーバーロードを呼び出すことができるようswap
に、修飾されていない方法で呼び出しswap
ます。提供されている型と同じ名前空間で宣言されたカスタムオーバーロードが選択されます通じ引数依存の検索このジェネリック版を超えます。
ただしstd::swap
、ユーザー定義クラスの関数を直接使用すると、ユーザー定義のstd::swap
代わりにの汎用バージョンが呼び出されることに注意してくださいswap
。
my::object a, b;
std::swap(a, b); // calls std::swap, not my::swap
したがってswap
、標準ライブラリで行われるのと同じ方法で、ユーザーコードで関数を呼び出すことをお勧めします。
my::object a, b;
using std::swap;
swap(a, b); // calls my::swap if it is defined, or std::swap if it is not.