[解決済み] C++コンテナにおけるイテレータの無効化ルール
質問
C++コンテナにおけるイテレータの無効化ルールとは?
<サブ ( 注意してください。 このQ&Aは、以下のエントリです。 スタックオーバーフローのC++FAQ . この質問に関するメタディスカッションは、以下のサイトに投稿してください。 すべての始まりとなったメタな質問 ここではない)解決方法は?
C++17 (参考文献はすべてCPP17の最終作業草案から -) n4659 )
挿入
配列コンテナ
-
vector
: 機能insert
,emplace_back
,emplace
,push_back
は、新しいサイズが古い容量より大きい場合、再割当を引き起こします。再割り当ては、シーケンス内の要素を参照しているすべての参照、ポインタ、イテレータを無効にします。再割り当てが行われない場合 が発生した場合、挿入ポイント以前のすべてのイテレータと参照は有効なままである。[26.3.11.5/1]
に関してはreserve
関数の再割り当ては、シーケンス内の要素を参照しているすべての参照、ポインタ、イテレータを無効にします。を呼び出した後に起こる挿入の間,再割り当てを行ってはならない。reserve()
挿入によってベクトルのサイズがcapacity()
. [26.3.11.3/6] -
deque
: deque の途中への挿入は、deque のすべてのイテレータと要素への参照を無効にする。deque の両端への挿入は、deque のすべてのイテレータを無効にするが、 deque の要素への参照の有効性には影響を与えない。[26.3.8.4/1] -
list
: イテレータやリファレンスの有効性に影響を与えない。例外が発生しても影響はない。[26.3.10.4/1].
は、そのinsert
,emplace_front
,emplace_back
,emplace
,push_front
,push_back
関数は、このルールの対象となる。 -
forward_list
: のオーバーロードは、いずれもinsert_after
は、イテレータと参照の有効性に影響を与えるものとする[26.3.9.5/1]。 -
array
: 原則として 配列へのイテレータは、その配列のライフタイムを通じて決して無効にはなりません。しかし、入れ替えの際には、イテレータは同じ配列要素を指し続けるので、値が変わってしまうことに注意しなければなりません。
アソシアティブコンテナ
-
All Associative Containers
: はinsert
とemplace
メンバは,イテレータ及びコンテナへの参照の有効性に影響を及ぼしてはならない[26.2.6/9] 。
非順序型連想コンテナ
-
All Unordered Associative Containers
: リハッシュはイテレータを無効にし、要素間の順序を変更し、要素が出現するバケットを変更しますが、要素へのポインタや参照は無効にしません。[26.2.7/9]
そのinsert
とemplace
メンバは,コンテナ要素への参照の有効性に影響を及ぼしてはならないが,コンテナへのすべてのイテレータを無効とすることができる。[26.2.7/14]
は、そのinsert
とemplace
の場合、メンバはイテレータの有効性に影響を与えないものとする。(N+n) <= z * B
ここでN
は、挿入操作前のコンテナ内の要素数です。n
は挿入された要素の数です。B
はコンテナのバケット数、そしてz
はコンテナの最大負荷率である。[26.2.7/15] -
All Unordered Associative Containers
: マージ操作の場合(例.a.merge(a2)
を参照するすべてのイテレータは、転送された要素を参照するイテレータになります。a
に残っている要素に対するイテレータは無効となります。a2
は有効であり続ける。(表 91 - 順不同の連想コンテナの要件)
コンテナ用アダプター
-
stack
: 基本コンテナから継承 -
queue
: 下のコンテナから継承 -
priority_queue
: 下のコンテナから継承
消去
シーケンスコンテナ
-
vector
: 機能erase
とpop_back
は,消去された時点以降のイテレータ及び参照を無効にする。[26.3.11.5/3] -
deque
: の最後の要素を消す消去操作。deque
は、過去の終了イテレータと、消去された要素へのすべてのイテレータと参照のみを無効にします。の最初の要素を消去する操作は、終了したイテレータと、消去された要素のすべてのイテレータと参照を無効にします。deque
最後の要素ではなく、イテレータとその要素への参照のみが無効となります。の最初の要素も最後の要素も消去しない消去操作では、消去された要素への参照のみが無効になります。deque
のすべての要素に対する過去の終了イテレータとすべてのイテレータと参照を無効にします。deque
. [ 注pop_front
とpop_back
は消去操作です。-終了メモ- ]。[26.3.8.4/4] -
list
: 消去された要素へのイテレータと参照のみを無効にする。[26.3.10.4/3]. これは、以下に適用されます。erase
,pop_front
,pop_back
,clear
関数を使用します。remove
とremove_if
メンバー関数です。リスト・イテレータが参照するリストの要素をすべて消去する関数です。i
で、以下の条件が成立するもの。*i == value
,pred(*i) != false
. 消去された要素へのイテレータと参照のみを無効化する[26.3.10.5/15]。unique
member function - イテレータが参照する連続した等しい要素群から、最初の要素以外を消去します。i
の範囲内で[first + 1, last)
に対して*i == *(i-1)
(引数なしのuniqueのバージョンの場合)またはpred(*i, *(i - 1))
(述語の引数を持つバージョンのuniqueの場合)が成立する。消去された要素へのイテレータと参照のみを無効化する。[26.3.10.5/19] -
forward_list
:erase_after
は,消去された要素へのイテレータ及び参照のみを無効とする。[26.3.9.5/1].remove
とremove_if
メンバ関数 - リスト・イテレータ i が参照するリストのうち、以下の条件が成立する要素を全て消去する。*i == value
(以下はremove()
),pred(*i)
が真になる(この場合remove_if()
). 消去された要素へのイテレータと参照のみを無効にする。[26.3.9.6/12].unique
メンバ関数 - イテレータiによって参照される連続した等しい要素群のうち, [first + 1, last]の範囲にあるものから,最初の要素以外を消去します。*i == *(i-1)
(引数なしのバージョンの場合)またはpred(*i, *(i - 1))
(述語引数付きバージョンの場合)が成立する。消去された要素へのイテレータと参照のみを無効化する。 [26.3.9.6/16] -
All Sequence Containers
:clear
は、aの要素を参照するすべての参照、ポインタ、イテレータを無効にし、過去の終了イテレータを無効にする場合があります(表87 - シーケンスコンテナの要件)。しかしforward_list
,clear
は、過去の終了イテレータを無効にしない。[26.3.9.5/32] -
All Sequence Containers
:assign
は、すべての参照、ポインタ、および コンテナの要素を参照するイテレータです。の場合vector
とdeque
は、過去に終了したイテレータも無効にする。(表87 - シーケンスコンテナの要件)
アソシアティブコンテナ
-
All Associative Containers
: はerase
メンバは,消去された要素へのイテレータ及び参照のみを無効化しなければならない[26.2.6/9]。 -
All Associative Containers
: はextract
メンバは、削除された要素へのイテレータのみを無効にします。削除された要素へのポインタと参照は有効なままです[26.2.6/10]。
コンテナ用アダプター
-
stack
: 基本コンテナから継承 -
queue
: 下のコンテナから継承 -
priority_queue
: 下のコンテナから継承
イテレータの無効化に関する一般的なコンテナ要件。
-
特に指定がない限り(明示的に、または他の関数で関数を定義することによって)、コンテナのメンバ関数を呼び出したり、ライブラリ関数の引数としてコンテナを渡しても、そのコンテナ内のオブジェクトへのイテレータを無効化したり、その値を変更したりしてはならない。[26.2.1/12]
-
いいえ
swap()
関数は、交換されるコンテナの要素を参照している参照、ポインタ、イテレータをすべて無効にします。[注意: end()イテレータはどの要素も参照していないので、無効になる可能性があります。-終了メモ- ]。[26.2.1/(11.6)]
上記の要求事項の例として
-
transform
アルゴリズムを使用します。はop
とbinary_op
関数は,イテレータ又はサブレンジを無効にしたり,範囲内の要素を変更してはならない [28.6.4/1] 。 -
accumulate
のアルゴリズムを使用しています。範囲[first, last]で。binary_op
は,要素を修正したり,反復子又は部分範囲を無効にしたりしてはならない[29.8.2/1]。 -
reduce
algorithm: binary_op は、イテレータやサブレンジを無効にしてはならないし、範囲 [first, last] 内の要素を変更してはならない。[29.8.3/5]
などなど...。
関連
-
[解決済み】coutはstdのメンバではない
-
[解決済み】エラー:strcpyがこのスコープで宣言されていない
-
[解決済み] 変数サイズのオブジェクトが初期化されないことがある c++
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] コピーアンドスワップ慣用句とは?
-
[解決済み] なぜC++はPythonよりもstdinからの行の読み込みが遅いのですか?
-
[解決済み] 未定義の動作とシーケンスポイント
-
[解決済み] C++で配列はどのように使うのですか?
-
[解決済み] コンパイル・リンクはどのように行われるのですか?
-
[解決済み】画像処理。コカ・コーラ缶」認識のためのアルゴリズム改良
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Visual Studio 2015で「非標準の構文。'&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み] [Solved] Error C1083: Cannot open include file: 'stdafx.h'
-
[解決済み] error: 'ostream' does not name a type.
-
[解決済み】C++のGetlineの問題(オーバーロードされた関数 "getline "のインスタンスがない
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】リンカーエラーです。"リンカ入力ファイルはリンクが行われていないため未使用"、そのファイル内の関数への未定義参照
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)