ノードハンドル (C++17)
template</*unspecified*/> class /*node-handle*/; |
(C++17以上) | |
連想コンテナ std::set, std::map, std::multiset, std::multimap, std::unordered_set, std::unordered_map, std::unordered_multiset, std::unordered_multimap はノードベースのデータ構造を持ち、そのノードをノードハンドルと呼ばれる未規定の型のオブジェクトとして抽出できます。
ノードハンドルはムーブオンリーな型で、そのノードに格納された要素 (value_type
) へのアクセスを提供し、またその要素のキーの部分 (key_type
) への非 const なアクセスを提供します。 ノードを保持しているノードハンドルの破棄が許される場合、そのノードはコンテナのための適切なアロケータを使用して正しく破棄されます。 ノードハンドルはコンテナのアロケータのコピーを持ちます。 これはノードハンドルがコンテナより長生きできるために必要です。
ノードハンドルの正確な型 (ここで /*node-handle*/ となっている部分) は未規定ですが、各コンテナはそのノードハンドルの型をメンバ node_type
として公開しています。
ノードハンドルは、同じキー型、値型、アロケータ型 (比較関数やハッシュは無視されます) を持つ2つの連想コンテナ間で、コンテナ要素に対するコピーもムーブも行わずに、要素の所有権を転送するために使用することができます (この種の操作は「スプライシング」と呼ばれます)。 一意でないコンテナと一意なコンテナの間の転送も許されています。 例えば std::map から抽出したノードハンドルは、 std::multimap に挿入することはできますが、 std::unordered_map や std::set には挿入できません。
ノードハンドルは空の場合もあります。 この場合は要素もアロケータも保持しません。 デフォルト構築されたノードハンドルや、ムーブされた後のノードハンドルは、空です。 また、空のノードハンドルは、コンテナのメンバ関数 extract
の呼び出しの失敗によっても生成されます。
ノードハンドルに所有されている間に取得した、要素を指すポインタや参照は、その要素のコンテナへの挿入が成功すると、無効化されます。
すべてのマップコンテナ (std::map, std::multimap, std::unordered_map, std::unordered_multimap) において、その key_type
を K
、 mapped_type
を T
としたとき、 std::pair<K, T> または std::pair<const K, T> に対するユーザ定義の std::pair の特殊化が存在する場合、ノードハンドルを用いる操作の動作は未定義になります。
目次 |
[編集] メンバ型
メンバ型 | 定義 |
key_type
|
Key
|
mapped_type
|
T
|
allocator_type
|
要素を破棄するときに使用されるアロケータ |
[編集] メンバ関数
コンストラクタ
constexpr /*node-handle*/() noexcept; |
(1) | |
/*node-handle*/(/*node-handle*/&& nh) noexcept; |
(2) | |
nh
からコンテナ要素の所有権を取得し、アロケータをムーブ構築し、 nh
を空の状態にします。引数
nh | - | 同じ型 (同じコンテナである必要はありません) ��ノードハンドル |
ノート
ノードハンドルはムーブオンリーであり、コピーコンストラクタは定義されません。
operator=
/*node-handle*/& operator=(/*node-handle*/&& nh); |
||
- ノードハンドルが空でない場合、
- このノードによって管理されているコンテナ要素オブジェクトの
value_type
サブオブジェクトを、std::allocator_traits<allocator_type>::destroy
を呼ぶことによって破棄します。 -
allocator_traits<allocator_type>::rebind_traits<container-node-type>::deallocate
を呼ぶことによって、コンテナ要素を解放します。
- このノードによって管理されているコンテナ要素オブジェクトの
-
nh
からコンテナ要素の所有権を取得します。 - ノードハンドルが元は空であった (そのためアロケータを保持していない) 場合、または
allocator_traits<allocator_type>::propagate_on_container_move_assignment
がtrue
の場合、アロケータをnh
からムーブ代入します。 -
nh
を空の状態に設定します。
ノードが空でなく、 allocator_traits<allocator_type>::propagate_on_container_move_assignment
が false
で、アロケータを比較して等しくない場合、動作は未定義です。
引数
nh | - | 同じ型 (同じコンテナである必要はありません) のノードハンドル |
戻り値
*this
例外
(なし)
ノート
ノードハンドルはムーブオンリーで、コピー代入は定義されません。
デストラクタ
~/*node-handle*/(); |
||
- ノードハンドルが空でない場合、
- このノードハンドルによって管理されているコンテナ要素オブジェクト内の
value_type
サブオブジェクトを、std::allocator_traits<allocator_type>::destroy
を呼ぶことによって破棄します。 -
allocator_traits<allocator_type>::rebind_traits<container-node-type>::deallocate
を呼ぶことによってコンテナ要素を解放します。
- このノードハンドルによって管理されているコンテナ要素オブジェクト内の
empty
bool empty() const noexcept; |
(C++20未満) | |
[[nodiscard]] bool empty() const noexcept; |
(C++20以上) | |
ノードハンドルが空であれば true
、そうでなければ false
を返します。
operator bool
explicit operator bool() const noexcept; |
||
ノードハンドルが空であれば false
、そうでなければ true
を返します。
get_allocator
allocator_type get_allocator() const; |
||
格納されているアロケータ (元のコンテナのアロケータのコピー) を返します。 ノードハンドルが空の場合、動作は未定義です。
例外
(なし)
value
value_type& value() const; |
(set コンテナのみ) | |
このノードハンドルによって管理されているコンテナ要素オブジェクト内の value_type
サブオブジェクトを指す参照を返します。 ノードハンドルが空の場合、動作は未定義です。
例外
(なし)
key
key_type& key() const; |
(map コンテナのみ) | |
このノードハンドルによって管理されているコンテナ要素オブジェクト内の value_type
サブオブジェクトの key_type
メンバを指す非 const な参照を返します。 ノードハンドルが空の場合、動作は未定義です。
例外
(なし)
ノート
この関数を使用すると、要素をコピーもムーブもせずとも、マップから抽出したノードのキーを変更し、その後マップに再挿入することが可能となります。
mapped
mapped_type& mapped() const; |
(map コンテナのみ) | |
このノードハンドルによって管理されているコンテナ要素オブジェクト内の value_type
サブオブジェクトの mapped_type
メンバを指す参照を返します。 ノードハンドルが空の場合、動作は未定義です。
例外
(なし)
swap
void swap(/*node-handle*/& nh) noexcept(/* see below */); |
||
- コンテナノードの所有権を入れ替えます。
- 一方のノードが空であるか、両方のノードが空でなく
std::allocator_traits<allocator_type>::propagate_on_container_swap
がtrue
の場合、アロケータも同様に入れ替えられます。
両方のノードが空でなく、 allocator_traits<allocator_type>::propagate_on_container_swap
が false
で、アロケータを比較して等しくない場合、動作は未定義です。
例外
std::allocator_traits<allocator_type>::is_always_equal::value)
[編集] 非メンバ関数
swap
friend void swap(/*node-handle*/& x, /*node-handle*/& y) noexcept(noexcept(x.swap(y))); |
||
実質的に x.swap(y) を実行します。