名前空間
変種
操作

std::map<Key,T,Compare,Allocator>::挿入

From cppreference.com
< cpp‎ | コンテナ‎ | map
 
 
 
 
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 の場合にのみ参加します。
7) 範囲 `[``first``, ``last``)` から要素を挿入します。範囲内の複数の要素が同等なキーを持つ場合、どの要素が挿入されるかは未規定です(LWG2844 参照)。
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
型要件
-
InputItLegacyInputIterator の要件を満たす必要があります。

[編集] 戻り値

1-3) 挿入された要素(または挿入を妨げた要素)を指すイテレータと、挿入が行われた場合にのみ `true` に設定される `bool` 値で構成されるペア。
4-6) 挿入された要素、または挿入を妨げた要素を指すイテレータ。
7,8) (なし)
9) `insert_return_type` のオブジェクトで、メンバーは以下のように初期化されます。
  • nh が空の場合、insertedfalsepositionend()node は空になります。
  • それ以外の場合で、挿入が行われた場合、insertedtrueposition は挿入された要素を指し、node は空になります。
  • 挿入が失敗した場合、insertedfalsenodenh の以前の値になり、positionnh.key() と同等のキーを持つ要素を指します。
10) `nh` が空の場合は末尾イテレータ、挿入が行われた場合は挿入された要素を指すイテレータ、`nh.key()` と同等なキーを持つ要素への挿入が失敗した場合はそれを指すイテレータ。

[編集] 例外

1-6) いずれかの操作で例外がスローされた場合、挿入は効果がありません。

[編集] 計算量

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) の計算量は、
範囲 [firstlast)Compare に従ってソートされている場合、線形時間である必要がありました。
この特別なケースでは線形要件が削除されました。
LWG 316 C++98 オーバーロード (1) の戻り値において、どの `bool` 値が挿入成功を示すかは規定されていませんでした。
成功は `true` によって示されます。
成功は
`true` によって示されます。
LWG 2005 C++11 オーバーロード (2,5) は記述が不十分でした。 説明が改善されました。

[編集] 関連項目

(C++11)
要素を直接構築する
(公開メンバ関数) [編集]
ヒントを使用して要素を直接構築する
(公開メンバ関数) [編集]
要素を挿入するか、キーが既に存在する場合は現在の要素に代入する
(public member function) [編集]
引数から推論された型の std::insert_iterator を作成する
(関数テンプレート) [編集]
English 日本語 中文(简体) 中文(繁體)