std::map::insert
のセマンティクスに少し混乱しています。つまり、文句を言っているわけではありません。標準は標準であり、API はそのままです。まだ、
insert
意思
挿入操作は、挿入された各要素について、コンテナ内に同じキー値を持つ別の要素が既に存在するかどうかをチェックします。存在する場合、要素は挿入されず、マップされた値はまったく変更されません。
そして、引数が 1 つのバージョンの場合にのみpair<iterator,bool> insert ( const value_type& x );
、(新しい、おそらく異なる) 値をキーに挿入したかどうかさえ教えてくれます。私が理解している限り、キーが既に存在する場合、反復子バージョンは挿入を黙って無視します。
私にとって、これは単に直感に反するものであり、挿入時に値の部分が上書きされ、古い値の部分が破棄されることを期待していました。明らかに、STL の設計者の考えは異なっていました。(歴史的な) 理論的根拠を知っている人、または既存のセマンティクスが (より) 理にかなっている方法を完全に説明できる人はいますか?
例:
次のように、単一キー マップに挿入を実装する基本的な方法がいくつかありますstd::map
。
- 挿入、既に存在する場合は置換
- 挿入、既に存在する場合は無視 (これは std::map の動作です)
- 挿入、既に存在する場合はエラーをスロー
- 挿入、既に存在する場合は UB
私は今、なぜ(または)insert_or_ignore
よりも理にかなっているのかを理解しようとしています!insert_or_replace
insert_or_error
私は自分のTC++PLのコピーを調べました(残念ながら私はドイツ語版しか持っていません)。興味深いことに、Stroustrup は 17.4.1.7 章に書いています ( mapの操作をリストします): (ドイツ語からの大まかな翻訳で申し訳ありません)
insert()
(...) 通常、( ... ) の呼び出しの前に、キー(原文のまま!) が新しく挿入されたか、または既に存在していたかは気にしません。
マップの場合、提供された値が挿入された場合、または古い値がマップに残っている場合、かなりの違いが生じるため、これはsetにのみ当てはまり、 map には当てはまらないように私には思えます。(キーは同等であるため、明らかに重要ではありません。)
注: 私は、 Effective STLoperator[]
の項目 24とそこで提案されている関数について知っています。のセマンティクスの理論的根拠に興味があるのは、個人的には直観に反すると思うからです。efficientAddOrUpdate
insert