std::map<Key,T,Compare,Allocator>::挿入
From cppreference.com
| std::pair<iterator, bool> insert( const value_type& value ); |
(1) | |
| template< class P > std::pair<iterator, bool> insert( P&& value ); |
(2) | (C++11以降) |
| std::pair<iterator, bool> insert( value_type&& value ); |
(3) | (C++17以降) |
| (4) | ||
iterator insert( iterator pos, const value_type& value ); |
(C++11まで) | |
| iterator insert( const_iterator pos, const value_type& value ); |
(C++11以降) | |
| template< class P > iterator insert( const_iterator pos, P&& value ); |
(5) | (C++11以降) |
| iterator insert( const_iterator pos, value_type&& value ); |
(6) | (C++17以降) |
| template< class InputIt > void insert( InputIt first, InputIt last ); |
(7) | |
| void insert( std::initializer_list<value_type> ilist ); |
(8) | (C++11以降) |
| insert_return_type insert( node_type&& nh ); |
(9) | (C++17以降) |
| iterator insert( const_iterator pos, node_type&& nh ); |
(10) | (C++17以降) |
コンテナに要素を挿入します。コンテナが既に同等のキーを持つ要素を格納している場合は、挿入は行われません。
1-3) value を挿入します。
オーバーロード (2) は emplace(std::forward<P>(value)) と等価であり、オーバーロード解決には std::is_constructible<value_type, P&&>::value == true の場合にのみ参加します。
4-6) value を、pos の直前の位置にできるだけ近い位置に挿入します。
オーバーロード (5) は emplace_hint(hint, std::forward<P>(value)) と等価であり、オーバーロード解決には std::is_constructible<value_type, P&&>::value == true の場合にのみ参加します。
8) 初期化子リスト `ilist` から要素を挿入します。範囲内の複数の要素が同等なキーを持つ場合、どの要素が挿入されるかは未規定です(LWG2844 参照)。
9) nh が空の ノードハンドル の場合、何も行いません。それ以外の場合、コンテナに `nh.key()` と同等なキーを持つ要素が既に存在しない場合、`nh` が所有する要素をコンテナに挿入します。`nh` が空でなく、`get_allocator() != nh.get_allocator()` の場合、動作は未定義です。
10) nh が空の ノードハンドル の場合、何も行わず、末尾イテレータを返します。それ以外の場合、コンテナに `nh` が所有する要素を挿入します(コンテナに `nh.key()` と同等なキーを持つ要素が既に存在しない場合)。挿入の成功・失敗にかかわらず、`nh.key()` と同等なキーを持つ要素を指すイテレータを返します。挿入が成功した場合、`nh` はムーブされ、それ以外の場合は要素の所有権を保持します。要素は `pos` の直前の位置にできるだけ近い位置に挿入されます。`nh` が空でなく、`get_allocator() != nh.get_allocator()` の場合、動作は未定義です。
イテレータや参照は無効にされません。(C++17以降)挿入が成功した場合、ノードハンドル内で保持されていた要素へのポインタや参照は無効になり、ノードハンドルから抽出される前にその要素に対して取得されたポインタや参照は有効になります。
目次 |
[編集] パラメータ
| pos | - | 新しい要素が挿入される前の位置へのイテレータ |
| value | - | 挿入する要素の値 |
| first, last | - | 挿入する要素の範囲を定義するイテレータのペア |
| ilist | - | 挿入する値の初期化子リスト |
| nh | - | 互換性のある node handle |
| 型要件 | ||
-InputIt は LegacyInputIterator の要件を満たす必要があります。 | ||
[編集] 戻り値
1-3) 挿入された要素(または挿入を妨げた要素)を指すイテレータと、挿入が行われた場合にのみ `true` に設定される `bool` 値で構成されるペア。
4-6) 挿入された要素、または挿入を妨げた要素を指すイテレータ。
7,8) (なし)
9) `insert_return_type` のオブジェクトで、メンバーは以下のように初期化されます。
- nh が空の場合、
insertedは false、positionは end()、nodeは空になります。 - それ以外の場合で、挿入が行われた場合、
insertedは true、positionは挿入された要素を指し、nodeは空になります。 - 挿入が失敗した場合、
insertedは false、nodeは nh の以前の値になり、positionは nh.key() と同等のキーを持つ要素を指します。
10) `nh` が空の場合は末尾イテレータ、挿入が行われた場合は挿入された要素を指すイテレータ、`nh.key()` と同等なキーを持つ要素への挿入が失敗した場合はそれを指すイテレータ。
[編集] 例外
1-6) いずれかの操作で例外がスローされた場合、挿入は効果がありません。
| このセクションは未完成です 理由: ケース 7-10 |
[編集] 計算量
1-3) コンテナのサイズに対して対数時間、
O(log(size()))。4-6) 挿入が `pos` の直前(C++11まで直後)に行われる場合は償却定数時間、それ以外の場合はコンテナのサイズに対して対数時間。
7,8)
O(N·log(size() + N))、ここで `N` は挿入する要素数。9) コンテナのサイズに対して対数時間、
O(log(size()))。10) 挿入が `pos` の直前に行われる場合は償却定数時間、それ以外の場合はコンテナのサイズに対して対数時間。
[編集] 注記
ヒント付き挿入 (4-6) は、`std::vector::insert` のようなシーケンシャルコンテナの位置指定挿入とシグネチャ互換性を持たせるために、ブール値を返しません。これにより、`std::inserter` のようなジェネリックインサータを作成できます。ヒント付き挿入の成功を確認する一つの方法は、挿入前後の `size()` を比較することです。
[編集] 例
このコードを実行
#include <iomanip> #include <iostream> #include <map> #include <string> using namespace std::literals; template<typename It> void print_insertion_status(It it, bool success) { std::cout << "Insertion of " << it->first << (success ? " succeeded\n" : " failed\n"); } int main() { std::map<std::string, float> heights; // Overload 3: insert from rvalue reference const auto [it_hinata, success] = heights.insert({"Hinata"s, 162.8}); print_insertion_status(it_hinata, success); { // Overload 1: insert from lvalue reference const auto [it, success2] = heights.insert(*it_hinata); print_insertion_status(it, success2); } { // Overload 2: insert via forwarding to emplace const auto [it, success] = heights.insert(std::pair{"Kageyama", 180.6}); print_insertion_status(it, success); } { // Overload 6: insert from rvalue reference with positional hint const std::size_t n = std::size(heights); const auto it = heights.insert(it_hinata, {"Azumane"s, 184.7}); print_insertion_status(it, std::size(heights) != n); } { // Overload 4: insert from lvalue reference with positional hint const std::size_t n = std::size(heights); const auto it = heights.insert(it_hinata, *it_hinata); print_insertion_status(it, std::size(heights) != n); } { // Overload 5: insert via forwarding to emplace with positional hint const std::size_t n = std::size(heights); const auto it = heights.insert(it_hinata, std::pair{"Tsukishima", 188.3}); print_insertion_status(it, std::size(heights) != n); } auto node_hinata = heights.extract(it_hinata); std::map<std::string, float> heights2; // Overload 7: insert from iterator range heights2.insert(std::begin(heights), std::end(heights)); // Overload 8: insert from initializer_list heights2.insert({{"Kozume"s, 169.2}, {"Kuroo", 187.7}}); // Overload 9: insert node const auto status = heights2.insert(std::move(node_hinata)); print_insertion_status(status.position, status.inserted); node_hinata = heights2.extract(status.position); { // Overload 10: insert node with positional hint const std::size_t n = std::size(heights2); const auto it = heights2.insert(std::begin(heights2), std::move(node_hinata)); print_insertion_status(it, std::size(heights2) != n); } // Print resulting map std::cout << std::left << '\n'; for (const auto& [name, height] : heights2) std::cout << std::setw(10) << name << " | " << height << "cm\n"; }
出力
Insertion of Hinata succeeded Insertion of Hinata failed Insertion of Kageyama succeeded Insertion of Azumane succeeded Insertion of Hinata failed Insertion of Tsukishima succeeded Insertion of Hinata succeeded Insertion of Hinata succeeded Azumane | 184.7cm Hinata | 162.8cm Kageyama | 180.6cm Kozume | 169.2cm Kuroo | 187.7cm Tsukishima | 188.3cm
[編集] 不具合報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 233 | C++98 | pos は単なるヒントであり、完全に無視される可能性がありました。 | 挿入はpos の直前の位置にできるだけ近い位置に |
| 行われることが要求されました。 | C++98 | オーバーロード (7) の計算量は、線形であることが要求されました。 オーバーロード (5) の計算量は、 |
範囲 [first, last) が Compare に従ってソートされている場合、線形時間である必要がありました。この特別なケースでは線形要件が削除されました。 |
| LWG 316 | C++98 | オーバーロード (1) の戻り値において、どの `bool` 値が挿入成功を示すかは規定されていませんでした。 成功は `true` によって示されます。 |
成功は `true` によって示されます。 |
| LWG 2005 | C++11 | オーバーロード (2,5) は記述が不十分でした。 | 説明が改善されました。 |
[編集] 関連項目
| (C++11) |
要素を直接構築する (公開メンバ関数) |
| (C++11) |
ヒントを使用して要素を直接構築する (公開メンバ関数) |
| (C++17) |
要素を挿入するか、キーが既に存在する場合は現在の要素に代入する (public member function) |
| 引数から推論された型の std::insert_iterator を作成する (関数テンプレート) |