15

なぜ両方を教えてくれませんか

std::unordered_map::insert(const value_type&)

template<class P> std::unordered_map::insert(P&&)

標準に存在しますか?

私はそれinsert(P&&)がとして役立つことができると思いますinsert(const value_type&)

4

3 に答える 3

7

これらの過負荷の両方

auto std::unordered_map::insert(const value_type&) -> ...

template<class P>
auto std::unordered_map::insert(P&&) -> ...

それらの利点があり、どちらも完全に他を置き換えることはできません。最初のものは、と推定される可能性があるため、2番目のものの特殊なケースのように見えます。2番目のオーバーロードの良いところは、不要なコピーを回避できることです。たとえば、この場合:Pconst value_type&

mymap.insert(make_pair(7,"seven"));

ここで、make_pairの結果は実際にはaですが、はでpair<int, const char*>あるvalue_type可能性がありますpair<const int, string>。したがって、一時value_typeオブジェクトを作成してコンテナにコピーvalue_typeする代わりに、引数を変換したり、そのメンバーを移動したりすることで、オブジェクトをマップに直接作成することができます。

一方、これもうまくいくといいでしょう:

mymap.insert({7,"seven"});

しかし、このリストは実際には表現ではありません!そのため、コンパイラは2番目のオーバーロードのPを推測できません。pair<const int,string>このようなリストを使用してパラメーターをコピー初期化できるため、最初のオーバーロードは引き続き実行可能です。

于 2013-02-06T13:09:58.077 に答える
4

テンプレートユニバーサルリファレンスオーバーロードがn1858に追加されましたが、その理由は次のとおりです(の場合mapですが、同じことが明示的に適用されますmultimap)。

2つのinsert署名は新しいものです。value_typeこれらは、に変換可能な、以外の右辺値タイプからの移動を可能にするために追加されましたvalue_typeP左辺値としてインスタンス化する場合、引数はにコピーされます。それ以外の場合は、 (const修飾子が許可する)mapに移動されます。map

insert参照される他の署名は、ヒント付き挿入です。)

また、次の理由も参照しますdeque(ここでも、他のコンテナーについて明示的に参照されています)。

単一のvalue_typeをコンテナーに挿入(または追加、追加など)するすべてのメンバー関数は、単一のvalue_typeをコンテナーに移動できるように、右辺値参照によってそのvalue_typeを受け入れるメンバー関数でオーバーロードされます。これにより、重量のあるタイプでの作業がはるかに効率的になるだけでなく、移動可能であるがコピー不可能なタイプをコンテナに挿入することもできます。

変更が主に追加と見なされたことは明らかです。insertテンプレートのオーバーロードが元の(C ++ 03)を完全に置き換えることができるとは、当時は考慮されていませんでした。これは、以前のn1771を参照することで確認できます。これは、別のアプローチを使用して、テンプレートの過負荷の動機を提供します。

以下では、mapとmultimapの場合、2つの新しい挿入オーバーロードがあり、どちらも非constkey_typeとペアになっていることに注意してください。const key_typeから移動することはできないため、key_typeを(マルチ)マップに移動できるようにするには、ペアを使用する必要があります。const左辺値ペア​​と非const右辺値ペアの両方にオーバーロードがあるため、左辺値ペア​​はから移動されません。

pair<iterator, bool> insert(const value_type& x);  // CC
pair<iterator, bool> insert(const pair<key_type,mapped_type>& x);  // CC
pair<iterator, bool> insert(pair<key_type,mapped_type>&& x);

CCはの略語ですCopyConstructible。)

その場合、オーバーロードが冗長になったことに気付かずに、templateオーバーロードが追加されたようmapに見えます。冗長な過負荷を取り除くために、欠陥レポートを提出することを検討してください。multimapconst value_type &

于 2013-02-06T10:28:51.363 に答える
2

違いは、使用される参照のタイプにあります。最初

std::unordered_map::insert(const value_type&)

(C ++ 11)で左辺値参照と呼ばれるようになった参照(C ++ 03)を使用します。これはconstである必要があります。C ++ 11ではP&&、constである必要のない右辺値参照が導入されました。両方を可能にするために、2つの挿入機能が提供されています。

C++11のStackOverflowwrtrvalue Referencesでこの優れた回答をご覧ください。これが、あなたの質問に答えるのに役立つことを願っています。

C ++ 11でのT&&(ダブルアンパサンド)とはどういう意味ですか?

あなたが言ったように、rvalue-overloadを使用して、const lvalue refを渡すことは可能ですが、-http://msdn.microsoft.com/en-us/library/dd293668.aspxからこのテキストを参照してください。

関数をオーバーロードしてconst左辺値参照または右辺値参照を取得することにより、変更不可能なオブジェクト(左辺値)と変更可能な一時値(右辺値)を区別するコードを記述できます。

-ハンネス

于 2013-02-06T09:47:11.447 に答える