C++ 名前付き要件: UnorderedAssociativeContainer (C++11 以降)
順序なし連想コンテナは、キーに基づいてオブジェクトを高速に検索する機能を提供するContainerです。最悪の場合の計算量は線形ですが、平均的にはほとんどの操作で大幅に高速です。
順序なし連想コンテナは、Key; Hash (Key に対するハッシュ関数として機能するHash関数オブジェクト); および Pred (Key間の等価性を評価するBinaryPredicate) によってパラメータ化されます。std::unordered_map および std::unordered_multimap には、Key に関連付けられたマップ型 T もあります。
2つのKeyがPredに従って等しい場合、Hashは両方のキーに対して同じ値を返さなければなりません。
|
|
(C++20以降) |
std::unordered_map と std::unordered_set は特定のキーを持つ要素を最大1つまでしか含みませんが、std::unordered_multiset と std::unordered_multimap は代わりに同じキーを持つ複数の要素を持つことができます (これらは常にイテレーション時に隣接している必要があります)。
std::unordered_set および std::unordered_multiset の場合、値の型はキーの型と同じであり、iterator と const_iterator の両方が定数イテレータです。std::unordered_map および std::unordered_multimap の場合、値の型は std::pair<const Key, T> です。
順序なし連想コンテナの要素はバケットに整理され、同じハッシュを持つキーは同じバケットに格納されます。バケット内の要素の平均数を一定の値以下に保つために、コンテナのサイズが増加するとバケットの数が増加します。
リハッシュはイテレータを無効にし、要素が異なるバケットに再配置される可能性がありますが、要素への参照は無効になりません。
順序なし連想コンテナはAllocatorAwareContainerの要件を満たします。std::unordered_map および std::unordered_multimap の場合、AllocatorAwareContainer の value_type の要件は key_type および mapped_type に適用されます (value_type ではない)。
目次 |
[編集] 要件
凡例 | |
X
|
順序なし連想コンテナクラス |
| a | 型Xの値 |
| a2 | 型Xと互換性のあるノードを持つ型の値 |
| b | 型Xまたはconst Xの値 |
| a_uniq | Xが一意のキーをサポートする場合の型Xの値 |
| a_eq | Xが同等のキーをサポートする場合の型Xの値 |
| a_tran | 修飾子X::key_equal::is_transparentおよびX::hasher::is_transparentの両方が有効で型を示す場合の型Xまたはconst Xの値 |
| i, j | value_typeを参照する入力イテレータ |
[i, j)
|
有効な範囲 |
| rg (C++23以降) | container-compatible-range<value_type>をモデル化する型Rの値 |
| p, q2 | aへの有効な定数イテレータ |
| q, q1 | aへの有効なデリファレンス可能な定数イテレータ |
| r | aへの有効なデリファレンス可能なイテレータ |
[q1, q2)
|
aにおける有効な範囲 |
| il | 型std::initializer_list<value_type>の値 |
| t | 型X::value_typeの値 |
| k | 型key_typeの値 |
| hf | 型hasherまたはconst hasherの値 |
| eq | 型key_equalまたはconst key_equalの値 |
| ke | 次のような値
ここで、r1 および r2 は a_tran 内の要素のキーである。 |
| kx (C++23以降) | 次のような値
ここで、r1 および r2 は a_tran 内の要素のキーである。 |
| n | size_type型の値 |
| z | 型floatの値 |
| nh (C++17以降) | 型X::node_typeの右辺値 |
[編集] メンバ型
| 名前 | 型 | 要件 | 注釈 |
|---|---|---|---|
X::key_type
|
Key
|
||
X::mapped_type
|
T
|
std::unordered_map および std::unordered_multimap のみ | |
X::value_type
|
Key
|
std::unordered_set および std::unordered_multiset のみ。XでErasable |
|
| std::pair<const Key, T> | std::unordered_map および std::unordered_multimap のみ。XでErasable |
||
X::hasher
|
Hash
|
Hash | |
X::key_equal
|
Pred
|
CopyConstructible; Key型の2つの引数を取り、等価関係を表現するBinaryPredicate |
|
X::local_iterator
|
LegacyIterator | カテゴリと型は X::iterator と同じ |
単一のバケットを反復処理するために使用できるが、バケットをまたがることはできない。 |
X::const_local_iterator
|
LegacyIterator | カテゴリと型は X::const_iterator と同じ | |
X::node_type (C++17以降) |
ノードハンドルクラステンプレートの特殊化 | パブリックなネストされた型は X の対応する型と同じ |
[編集] メンバ関数と演算子
| Expression | 結果 | 事前条件 | 効果 | 戻り値 | 計算量 |
|---|---|---|---|---|---|
| X(n, hf, eq) | n個以上のバケットを持つ空のコンテナを構築し、ハッシュ関数としてhfを、キー等価述語としてeqを使用する | O(n) | |||
| X(n, hf) | key_equalはDefaultConstructibleである。 |
n個以上のバケットを持つ空のコンテナを構築し、ハッシュ関数としてhfを、キー等価述語としてkey_equal()を使用する | O(n) | ||
| X(n) | hasherとkey_equalはDefaultConstructibleである |
n個以上のバケットを持つ空のコンテナを構築し、ハッシュ関数としてhasher()を、キー等価述語としてkey_equal()を使用する | O(n) | ||
| X a = X(); X a; |
hasherとkey_equalはDefaultConstructibleである |
未指定の数のバケットを持つ空のコンテナを構築し、ハッシュ関数としてhasher()を、キー等価述語としてkey_equal()を使用する | Constant | ||
| X(i, j, n, hf, eq) | value_typeは*iからXにEmplaceConstructibleである |
n個以上のバケットを持つ空のコンテナを構築し、ハッシュ関数としてhfを、キー等価述語としてeqを使用し、[i, j)から要素を挿入する |
平均ケース O(N) (ここでN は std::distance(i, j)), 最悪ケース O(N2) | ||
| X(i, j, n, hf) | key_equalはDefaultConstructibleである。value_typeは*iからXにEmplaceConstructibleである |
n個以上のバケットを持つ空のコンテナを構築し、ハッシュ関数としてhfを、キー等価述語としてkey_equal()を使用し、[i, j)から要素を挿入する |
平均ケース O(N) (ここでN は std::distance(i, j)), 最悪ケース O(N2) | ||
| X(i, j, n) | hasherとkey_equalはDefaultConstructibleである。value_typeは*iからXにEmplaceConstructibleである |
n個以上のバケットを持つ空のコンテナを構築し、ハッシュ関数としてhasher()を、キー等価述語としてkey_equal()を使用し、[i, j)から要素を挿入する |
平均ケース O(N) (ここでN は std::distance(i, j)), 最悪ケース O(N2) | ||
| X(i, j) | hasherとkey_equalはDefaultConstructibleである。value_typeは*iからXにEmplaceConstructibleである |
未指定の数のバケットを持つ空のコンテナを構築し、ハッシュ関数としてhasher()を、キー等価述語としてkey_equal()を使用し、[i, j)から要素を挿入する |
平均ケース O(N) (ここでN は std::distance(i, j)), 最悪ケース O(N2) | ||
| X(std::from_range, rg, n, hf, eq) (C++23から) |
value_typeは*ranges::begin(rg)からXにEmplaceConstructibleである |
n個以上のバケットを持つ空のコンテナを構築し、ハッシュ関数としてhfを、キー等価述語としてeqを使用し、rgから要素を挿入する | 平均ケース O(N) (ここでN は ranges::distance(rg)), 最悪ケース O(N2) | ||
| X(std::from_range, rg, n, hf) (C++23から) |
key_equalはDefaultConstructibleである。value_typeは*ranges::begin(rg)からXにEmplaceConstructibleである |
n個以上のバケットを持つ空のコンテナを構築し、ハッシュ関数としてhfを、キー等価述語としてkey_equal()を使用し、rgから要素を挿入する | 平均ケース O(N) (ここでN は ranges::distance(rg)), 最悪ケース O(N2) | ||
| X(std::from_range, rg, n) (C++23から) |
hasherとkey_equalはDefaultConstructibleである。value_typeは*ranges::begin(rg)からXにEmplaceConstructibleである |
n個以上のバケットを持つ空のコンテナを構築し、ハッシュ関数としてhasher()を、キー等価述語としてkey_equal()を使用し、rgから要素を挿入する | 平均ケース O(N) (ここでN は ranges::distance(rg)), 最悪ケース O(N2) | ||
| X(std::from_range, rg) (C++23から) |
hasherとkey_equalはDefaultConstructibleである。value_typeは*ranges::begin(rg)からXにEmplaceConstructibleである |
未指定の数のバケットを持つ空のコンテナを構築し、ハッシュ関数としてhasher()を、キー等価述語としてkey_equal()を使用し、rgから要素を挿入する | 平均ケース O(N) (ここでN は ranges::distance(rg)), 最悪ケース O(N2) | ||
| X(il) | X(il.begin(), il.end()) | ||||
| X(il, n) | X(il.begin(), il.end(), n) | ||||
| X(il, n, hf) | X(il.begin(), il.end(), n, hf) | ||||
| X(il, n, hf, eq) | X(il.begin(), il.end(), n, hf, eq) | ||||
| X(b) | Container; ハッシュ関数、述語、最大ロードファクタをコピーする | b.size()に対し平均ケースは線形、最悪ケースはO(N2) | |||
| a = b | X&
|
Container; ハッシュ関数、述語、最大ロードファクタをコピーする | b.size()に対し平均ケースは線形、最悪ケースはO(N2) | ||
| a = il | X&
|
value_typeはXにCopyInsertableであり、CopyAssignableである |
範囲[il.begin(), il.end())をaに代入する。aの既存の要素はすべて代入されるか破棄される |
il.size()に対し平均ケースは線形、最悪ケースはO(N2) | |
| b.hash_function() | hasher
|
bのハッシュ関数 | Constant | ||
| b.key_eq() | key_equal
|
bのキー等価述語 | Constant | ||
| a_uniq.emplace(args) | std::pair< iterator, bool> |
value_typeはargsからXにEmplaceConstructibleである |
std::forward<Args>(args)...で構築されたvalue_typeオブジェクトtを、コンテナにtのキーと等価なキーを持つ要素が存在しない場合に限り挿入する |
返されたペアのboolコンポーネントは、挿入が行われた場合にのみtrueであり、ペアのイテレータコンポーネントはtのキーと等価なキーを持つ要素を指す | 平均ケース O(1), 最悪ケース O(a_uniq.size()) |
| a_eq.emplace(args) | iterator
|
value_typeはargsからXにEmplaceConstructibleである |
std::forward<Args>(args)...で構築されたvalue_typeオブジェクトtを挿入する |
新しく挿入された要素を指すイテレータ | 平均ケース O(1), 最悪ケース O(a_eq.size()) |
| a.emplace_hint(p, args) | iterator
|
value_typeはargsからXにEmplaceConstructibleである |
a.emplace( std::forward<Args>(args)...) |
新しく挿入された要素とキーが等価な要素を指すイテレータ。const_iteratorpは検索を開始すべき場所を指すヒントである。実装はヒントを無視してもよい |
平均ケース O(1), 最悪ケース O(a.size()) |
| a_uniq.insert(t) | std::pair< iterator, bool> |
tが非const右辺値の場合、value_typeはXにMoveInsertableである。それ以外の場合、value_typeはXにCopyInsertableである |
tのキーと同等のキーを持つ要素がコンテナ内に存在しない場合に限り、tを挿入する | 返されたペアのboolコンポーネントは挿入が行われたかどうかを示し、iteratorコンポーネントはtのキーと同等のキーを持つ要素を指す |
平均ケース O(1), 最悪ケース O(a_uniq.size()) |
| a_eq.insert(t) | iterator
|
tが非const右辺値の場合、value_typeはXにMoveInsertableである。それ以外の場合、value_typeはXにCopyInsertableである |
tを挿入する | 新しく挿入された要素を指すイテレータ | 平均ケース O(1), 最悪ケース O(a_eq.size()) |
| a.insert(p, t) | iterator
|
tが非const右辺値の場合、value_typeはXにMoveInsertableである。それ以外の場合、value_typeはXにCopyInsertableである |
a.insert(t)。イテレータpは検索を開始すべき場所を指すヒントである。実装はヒントを無視してもよい | tのキーと同等のキーを持つ要素を指すイテレータ | 平均ケース O(1), 最悪ケース O(a.size()) |
| a.insert(i, j) | void | value_typeは*iからXにEmplaceConstructibleである。iもjもa内のイテレータではない |
各要素に対してa.insert(t)[i, j)
|
平均ケース O(N) (ここでN は std::distance(i, j)), 最悪ケース O(N·(a.size() + 1)) | |
| a.insert_range(rg) (C++23から) |
void | value_typeは*ranges::begin(rg)からXにEmplaceConstructibleである。rgとaは重複しない |
rg内の各要素tに対してa.insert(t) | 平均ケース O(N) (ここでN は ranges::distance(rg)), 最悪ケース O(N·(a.size() + 1)) | |
| a.insert(il) | a.insert(il.begin(), il.end()) | ||||
| a_uniq.insert(nh) (C++17以降) |
insert_return_type
|
nhが空であるか、または a_uniq.get_allocator() |
nhが空の場合、効果はなく、そうでない場合、nhが所有する要素を、コンテナにnh.key()と同等のキーを持つ要素が存在しない場合に限り挿入する。保証: nhが空の場合、insertedはfalse、positionはend()、nodeは空である。そうでない場合、挿入が行われた場合、insertedはtrue、positionは挿入された要素を指し、nodeは空である。挿入が失敗した場合、insertedはfalse、nodeはnhの以前の値を持ち、positionはnh.key()と同等のキーを持つ要素を指す | 平均ケース O(1), 最悪ケース O(a_uniq.size()) | |
| a_eq.insert(nh) (C++17以降) |
iterator
|
nhが空であるか、または a_eq.get_allocator() |
nhが空の場合、効果はなくa_eq.end()を返す。それ以外の場合、nhが所有する要素を挿入し、新しく挿入された要素を指すイテレータを返す。保証: nhは空である | 平均ケース O(1), 最悪ケース O(a_eq.size()) | |
| a.insert(q, nh) (C++17以降) |
iterator
|
nhが空であるか、または a.get_allocator() |
nhが空の場合、効果はなくa.end()を返す。それ以外の場合、一意のキーを持つコンテナではnh.key()と同等のキーを持つ要素が存在しない場合に限り、nhが所有する要素を挿入する。同等のキーを持つコンテナでは常にnhが所有する要素を挿入する。イテレータqは検索を開始すべき場所を指すヒントである。実装はヒントを無視してもよい。保証: 挿入が成功した場合、nhは空である。挿入が失敗した場合、変更なし | nh.key()とキーが等価な要素を指すイテレータ | 平均ケース O(1), 最悪ケース O(a.size()) |
| a.extract(k) (C++17以降) |
node_type
|
kと同等のキーを持つコンテナ内の要素を削除する | 要素が見つかった場合は要素を所有するnode_type、そうでなければ空のnode_type |
平均ケース O(1), 最悪ケース O(a.size()) | |
| a_tran.extract(kx) (C++23から) |
node_type
|
kxと同等のキーを持つコンテナ内の要素を削除する | 要素が見つかった場合は要素を所有するnode_type、そうでなければ空のnode_type |
平均ケース O(1), 最悪ケース O(a_tran.size()) | |
| a.extract(q) (C++17以降) |
node_type
|
qが指す要素を削除する | その要素を所有するnode_type |
平均ケース O(1), 最悪ケース O(a.size()) | |
| a.merge(a2) (C++17以降) |
void | a.get_allocator() == a2.get_allocator() |
a2内の各要素を抽出し、aのハッシュ関数とキー等価述語を使用してaに挿入しようと試みる。一意のキーを持つコンテナでは、aにa2からの要素のキーと同等のキーを持つ要素が存在する場合、その要素はa2から抽出されない。保証: 転送されたa2の要素へのポインタと参照は、同じ要素を参照するが、aのメンバとして参照する。転送された要素を参照するイテレータおよびaを参照するすべてのイテレータは無効になるが、a2に残る要素へのイテレータは有効なままとなる | 平均ケース O(N) (ここでN は a2.size()), 最悪ケース O(N·(a.size() + 1)) | |
| a.erase(k) | size_type
|
kと同等のキーを持つすべての要素を消去する | 消去された要素の数 | 平均ケース O(a.count(k)), 最悪ケース O(a.size()) | |
| a_tran.erase(kx) (C++23から) |
size_type
|
kxと同等のキーを持つすべての要素を消去する | 消去された要素の数 | 平均ケース O(a_tran.count(kx)), 最悪ケース O(a_tran.size()) | |
| a.erase(q) | iterator
|
qが指す要素を消去する | 消去直前のqの直後のイテレータ | 平均ケース O(1), 最悪ケース O(a.size()) | |
| a.erase(r) (C++17以降) |
iterator
|
rが指す要素を消去する | 消去直前のrの直後のイテレータ | 平均ケース O(1), 最悪ケース O(a.size()) | |
| a.erase(q1, q2) | iterator
|
範囲内のすべての要素を消去する[q1, q2)
|
消去直前の消去された要素の直後のイテレータ | 平均ケース O(N) (ここでN は std::distance(q1, q2)), 最悪ケース O(a.size()) | |
| a.clear() | void | コンテナ内のすべての要素を消去する。保証: a.empty()はtrueである | a.size()に対して線形 | ||
| b.find(k) | iterator; 定数bの場合はconst_iterator |
kと同等のキーを持つ要素を指すイテレータ、またはそのような要素が存在しない場合はb.end() | 平均ケース O(1), 最悪ケース O(b.size()) | ||
| a_tran.find(ke) (C++17以降)? |
iterator; 定数a_tranの場合はconst_iterator |
keと同等のキーを持つ要素を指すイテレータ、またはそのような要素が存在しない場合はa_tran.end() | 平均ケース O(1), 最悪ケース O(a_tran.size()) | ||
| b.count(k) | size_type
|
kと同等のキーを持つ要素の数 | 平均ケース O(b.count(k)), 最悪ケース O(b.size()) | ||
| a_tran.count(ke) (C++17以降)? |
size_type
|
keと同等のキーを持つ要素の数 | 平均ケース O(a_tran.count(ke)), 最悪ケース O(a_tran.size()) | ||
| b.contains(k) (C++20以降)? |
b.find(k) != b.end() | ||||
| a_tran.contains(ke) (C++20以降)? |
a_tran.find(ke) != a_tran.end() | ||||
| b.equal_range(k) | std::pair< iterator, iterator>; std::pair< |
kと同等のキーを持つすべての要素を含む範囲。そのような要素が存在しない場合、次を返す std::make_pair( |
平均ケース O(b.count(k)), 最悪ケース O(b.size()) | ||
| a_tran.equal_range(ke) (C++20以降)? |
std::pair< iterator, iterator>; std::pair< |
keと同等のキーを持つすべての要素を含む範囲。そのような要素が存在しない場合、次を返す std::make_pair( |
平均ケース O(a_tran.count(ke)), 最悪ケース O(a_tran.size()) | ||
| b.bucket_count() | size_type
|
bに含まれるバケットの数 | Constant | ||
| b.max_bucket_count() | size_type
|
bが包含できるバケットの数の上限 | Constant | ||
| b.bucket(k) | size_type
|
b.bucket_count() > 0 | kと同等のキーを持つ要素が存在する場合に、その要素が見つかるバケットのインデックス。戻り値は[0, b.bucket_count())の範囲内にある |
Constant | |
| a_tran.bucket(ke) | size_type
|
a_tran. bucket_count() > 0 |
keと同等のキーを持つ要素が存在する場合に、その要素が見つかるバケットのインデックス。戻り値は[0, a_tran.bucket_count())の範囲内にある |
Constant | |
| b.bucket_size(n) | size_type
|
nは[0, b.bucket_count())の範囲内にある |
n番目のバケット内の要素の数 | O(b.bucket_size(n)) | |
| b.begin(n) | local_iterator; 定数bの場合はconst_local_iterator |
nは[0, b.bucket_count())の範囲内にある |
バケット内の最初の要素を参照するイテレータ。バケットが空の場合、b.begin(n) == b.end(n) | Constant | |
| b.end(n) | local_iterator; 定数bの場合はconst_local_iterator |
nは[0, b.bucket_count())の範囲内にある |
バケットの過去終端値であるイテレータ | Constant | |
| b.cbegin(n) | const_local_iterator
|
nは[0, b.bucket_count())の範囲内にある |
バケット内の最初の要素を参照するイテレータ。バケットが空の場合、b.cbegin(n) == b.cend(n) | Constant | |
| b.cend(n) | const_local_iterator
|
nは[0, b.bucket_count())の範囲内にある |
バケットの過去終端値であるイテレータ | Constant | |
| b.load_factor() | float | バケットあたりの要素の平均数 | Constant | ||
| b.max_load_factor() | float | コンテナがロードファクタを等しいかそれ以下に保とうと試みる正の数。コンテナは、ロードファクタをこの数以下に保つために、必要に応じてバケットの数を自動的に増加させる | Constant | ||
| a.max_load_factor(z) | void | zは正の値である。zをヒントとして使用して、コンテナの最大ロードファクタを変更してもよい | Constant | ||
| a.rehash(n) | void | 保証 a.bucket_count() >= |
a.size()に対し平均ケースは線形、最悪ケースはO(N2) | ||
| a.reserve(n) | a.rehash(std::ceil( n / a.max_load_factor())) |
| このセクションは未完成です 理由: メンバ関数に関する要件。 |
[編集] 標準ライブラリ
以下の標準ライブラリコンテナはUnorderedAssociativeContainer要件を満たす
| (C++11) |
キーによってハッシュ化されたユニークなキーのコレクション (クラステンプレート) |
| (C++11) |
キーのコレクション、キーによってハッシュ化される (class template) |
| (C++11) |
キーによってハッシュ化されたキーと値のペアのコレクション、キーはユニーク (クラステンプレート) |
| (C++11) |
キーでハッシュ化されたキーと値のペアのコレクション (クラステンプレート) |
[編集] 欠陥レポート
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 2156 | C++11 | リハッシュ後のロードファクタは、 最大ロードファクタよりも厳密に低い |
等しくすることが許可されている |