名前空間
変種
操作

std::set<Key,Compare,Allocator>::insert

From cppreference.com
< cpp‎ | コンテナ‎ | set
 
 
 
 
std::pair<iterator, bool> insert( const value_type& value );
(1)
std::pair<iterator, bool> insert( value_type&& value );
(2) (C++11以降)
(3)
iterator insert( iterator pos, const value_type& value );
(C++11まで)
iterator insert( const_iterator pos, const value_type& value );
(C++11以降)
iterator insert( const_iterator pos, value_type&& value );
(4) (C++11以降)
template< class InputIt >
void insert( InputIt first, InputIt last );
(5)
void insert( std::initializer_list<value_type> ilist );
(6) (C++11以降)
insert_return_type insert( node_type&& nh );
(7) (C++17以降)
iterator insert( const_iterator pos, node_type&& nh );
(8) (C++17以降)
template< class K >
std::pair<iterator, bool> insert( K&& x );
(9) (C++23から)
template< class K >
iterator insert( const_iterator pos, K&& x );
(10) (C++23から)

コンテナに要素を挿入します。コンテナが既に同等のキーを持つ要素を格納している場合は、挿入は行われません。

1,2) value を挿入します。
3,4) pos の直前の位置にできるだけ近い位置に value を挿入します。
5) 範囲 [firstlast) から要素を挿入します。範囲内の複数の要素が同等のキーを持つ場合、どの要素が挿入されるかは未定義です(LWG2844 参照)。
6) 初期化子リスト ilist から要素を挿入します。範囲内の複数の要素が同等のキーを持つ場合、どの要素が挿入されるかは未定義です(LWG2844 参照)。
7) nh が空の node handle の場合、何も行いません。それ以外の場合は、nh が所有する要素をコンテナに挿入します。コンテナが既に nh.key() と同等のキーを持つ要素を格納している場合は、挿入は行われません。 nh が空でなく、かつ get_allocator() != nh.get_allocator() の場合、動作は未定義です。
8) nh が空の node handle の場合、何も行わず、end iterator を返します。それ以外の場合は、nh が所有する要素をコンテナに挿入します。コンテナが既に nh.key() と同等のキーを持つ要素を格納している場合は、挿入は行われません。挿入された要素へのイテレータを返します(挿入が成功したか失敗したかに関わらず、nh.key() と同等のキーを持つ要素を指します)。挿入が成功した場合、nh はムーブされ、それ以外の場合は要素の所有権を保持します。要素は pos の直前の位置にできるだけ近い位置に挿入されます。 nh が空でなく、かつ get_allocator() != nh.get_allocator() の場合、動作は未定義です。
9) *this が既に x と透明に比較して同等な要素を格納している場合、何も行いません。それ以外の場合、std::forward<K>(x) を用いて value_type のオブジェクト u を構築し、その後 u*this に挿入します。equal_range(u) == equal_range(x)false の場合、動作は未定義です。value_type は、std::forward<K>(x) から setEmplaceConstructible である必要があります。このオーバーロードは、修飾子 Compare::is_transparent が有効であり、型を指している場合にのみオーバーロード解決に参加します。これにより、Key のインスタンスを構築せずにこの関数を呼び出すことができます。
10) *this が既に x と透明に比較して同等な要素を格納している場合、何も行いません。それ以外の場合、std::forward<K>(x) を用いて value_type のオブジェクト u を構築し、その後 u*this に挿入します。挿入は pos の直前の位置にできるだけ近い位置に行われます。equal_range(u) == equal_range(x)false の場合、動作は未定義です。value_type は、std::forward<K>(x) から setEmplaceConstructible である必要があります。このオーバーロードは、
  • std::is_convertible_v<K&&, const_iterator> および std::is_convertible_v<K&&, iterator> が両方とも false であり、
  • かつ、修飾子 Compare::is_transparent が有効であり、型を指している場合に参加します。
これにより、Key のインスタンスを構築せずにこの関数を呼び出すことができます。

イテレータや参照は無効にされません。(C++17以降)挿入が成功した場合、ノードハンドル内で保持されていた要素へのポインタや参照は無効になり、ノードハンドルから抽出される前にその要素に対して取得されたポインタや参照は有効になります。

目次

[編集] パラメータ

pos - 新しい要素が挿入される前の位置へのイテレータ
value - 挿入する要素の値
first, last - 挿入する要素のソース 範囲 を定義するイテレータのペア
ilist - 挿入する値の初期化子リスト
nh - 互換性のある node handle
x - キーと透過的に比較できる任意の型の値
型要件
-
InputItLegacyInputIterator の要件を満たす必要があります。

[編集] 戻り値

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

[編集] 例外

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

[編集] 計算量

1,2) コンテナのサイズに対する対数時間、O(log(size()))
3,4) pos の直後に挿入が行われる場合は償却定数時間、それ以外の場合はコンテナのサイズに対する対数時間。
5,6) N を挿入する要素の数とすると、O(N·log(size() + N))
7) コンテナのサイズに対する対数時間、O(log(size()))
8) pos の直前に挿入が行われる場合は償却定数時間、それ以外の場合はコンテナのサイズに対する対数時間。
9) コンテナのサイズに対する対数時間、O(log(size()))
10) pos の直前に挿入が行われる場合は償却定数時間、それ以外の場合はコンテナのサイズに対する対数時間。

[編集] 注釈

ヒント付き挿入 (3,4) は、std::vector::insert のようなシーケンシャルコンテナの位置指定挿入とシグネチャ互換性を持たせるために、ブール値を返しません。これにより、std::inserter のようなジェネリックインサーターを作成できます。ヒント付き挿入の成功を確認する一つの方法は、挿入前後の size() を比較することです。

オーバーロード (5,6) は、end() をヒントとしてオーバーロード (3) を呼び出すループとして実装されることが多く、ソート済みのシーケンス(別の std::set など)を、*this の最後の要素より大きい最小要素で追加する場合に最適化されています。

機能テストマクロ 規格 機能
__cpp_lib_associative_heterogeneous_insertion 202311L (C++26) 順序付きおよび順序なし連想コンテナの残りのメンバ関数に対する異種オーバーロード。(9,10)

[編集]

#include <cassert>
#include <iostream>
#include <set>
 
int main()
{
    std::set<int> set;
 
    auto result_1 = set.insert(3);
    assert(result_1.first != set.end()); // it is a valid iterator
    assert(*result_1.first == 3);
    if (result_1.second)
        std::cout << "insert done\n";
 
    auto result_2 = set.insert(3);
    assert(result_2.first == result_1.first); // same iterator
    assert(*result_2.first == 3);
    if (!result_2.second)
        std::cout << "no insertion\n";
}

出力

insert done
no insertion

[編集] 却下されたレポート

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
LWG 233 C++98 pos は単なるヒントであり、完全に無視される可能性がありました。 挿入は
pos の直前の
位置にできるだけ近い位置に
行われることが要求されました。 C++98 LWG 264
オーバーロード (5) の計算量は、
範囲 [firstlast)Compare に従ってソートされている場合、線形時間である必要がありました。
この特別なケースでは線形要件が削除されました。
LWG 316 C++98 オーバーロード (1) の戻り値において、
どの bool 値が成功した挿入を示すかは指定されていませんでした。
成功は true
示されます。

[編集] 関連項目

(C++11)
要素を直接構築する
(公開メンバ関数) [編集]
ヒントを使用して要素を直接構築する
(公開メンバ関数) [編集]
引数から推論された型の std::insert_iterator を作成する
(関数テンプレート) [編集]
English 日本語 中文(简体) 中文(繁體)