名前空間
変種
操作

名前付き要件: Swappable

提供: cppreference.com
< cpp‎ | named req
 
 
名前付き要件
 

この型の任意の左辺値または右辺値は、 std::swap とユーザ定義の swap() の両方が可視な分脈において、無修飾の関数呼び出し swap() を使用して、何らかの別の型の任意の左辺値または右辺値とスワップすることができます。

目次

[編集] 要件

型 U の任意のオブジェクト u および型 T の任意のオブジェクト t について、以下の内容を満たす場合、型 U は型 T とスワップ可能です。

要件 セマンティクス
#include <utility>

using std::swap;
swap(u, t);

呼び出しの後、 t の値は呼び出し前に u が保持していた値となり、 u の値は呼び出し前に t が保持していた値となる。 引数依存の名前探索およびヘッダ <utility> で定義されている2つの std::swap テンプレートによって見つかった swap という名前を持つすべての関数に渡るオーバーロード解決によって見つかった swap 関数を呼びます。
#include <utility>

using std::swap;
swap(t, u);

同上。 同上。

多くの標準ライブラリの関数 (例えば多くのアルゴリズム) は、その引数が Swappable であることを期待します。 これは、標準ライブラリが swap を行うときは using std::swap; swap(t, u); と同等のコードを使用することを意味します。

一般的な実装は、以下のいずれかです。

1) 囲んでいる名前空間で非メンバの swap を定義します。 非パブリックデータメンバへのアクセスが必要な場合はメンバの swap に転送するかもしれません。
2) クラス内 friend 関数を定義する (この手法は ADL 以外の名前探索からクラス固有の swap を隠蔽します)。

[編集] ノート

標準ライブラリの関数が swap を行うとき、 <utility> が実際にインクルードされるかどうかは未規定です。 そのためユーザ提供の swap() はそれがインクルードされていると期待するべきではありません。

[編集]

#include <iostream>
#include <vector>
 
class IntVector {
    std::vector<int> v;
    IntVector& operator=(IntVector); // not assignable
 public:
    void swap(IntVector& other) {
        v.swap(other.v);
    }
};
void swap(IntVector& v1, IntVector& v2) {
    v1.swap(v2);
}
 
int main()
{
    IntVector v1, v2;
//  std::swap(v1, v2); // compiler error! std::swap requires MoveAssignable
    std::iter_swap(&v1, &v2); // OK: library calls unqualified swap()
}


[編集] 関連項目

その型のオブジェクトが同じ型または何らかの別の型のオブジェクトと swap 可能かどうか調べます
(クラステンプレート) [edit]