1

C++11 の場合、以下の間にパフォーマンスの違いはまだありますか?

std::map<Foo, std::vector<Bar> >例として)

map[key] = myVector and map.emplace(key, myVector)

私が理解していない部分は、operator[] の正確な内部です。これまでの私の理解は(キーが存在しない場合):

  1. マップ内に新しいキーと関連する空のデフォルト ベクトルを作成します。
  2. 関連付けられた空ベクトルの参照を返します
  3. myVector を参照に割り当てる???

ポイント3は私が理解できなかった部分ですが、そもそも参照に新しい値をどのように割り当てることができますか?

ポイント3を整理することはできませんが、何とかコピー/移動が必要だと思います。C++11 が移動操作になることを知るのに十分スマートであると仮定すると、この "[]" 割り当て全体は、insert() よりもすでに安価ですか? emplace() とほぼ同等ですか? ---- デフォルトの構築とコンテンツの移動と、コンテンツを直接配置した構築ベクトルとは?

4

1 に答える 1

3

両者には多くの違いがあります。

を使用するとoperator[]デフォルトで値が構築されます。からの戻り値は、このデフォルトで構築されたオブジェクトになり、それを使用して代入されます。mapoperator[]operator=

を使用する場合emplacemapは指定したパラメータを使用して値を直接構築します。

したがって、このoperator[]方法では常に 2 段階の構築が使用されます。デフォルトのコンストラクターが遅い場合、またはコピー/移動の構築がコピー/移動の代入よりも高速である場合、問題が発生する可能性があります。

ただし、指定されたキーが既に存在する場合、値は置き換えemplaceられません。一方、値があったかどうかに関係なく、常に値が置き換えられます。operator[]operator=

他にも違いがあります。コピー/移動がスローされた場合、が変更されないことがemplace保証されます。対照的に、は常にデフォルトの構成要素を挿入します。したがって、後のコピー/移動割り当てが失敗した場合、は既に変更されています。そのキーは、構築されたデフォルトで存在します。map operator[]mapvalue_type

実際、どちらを使用するかを決定する際に、最初に考慮すべきことはパフォーマンスではありません。最初に、目的の動作があるかどうかに注目する必要があります。

C++17 は、 の効果を持つを提供insert_or_assignmap[] = v;しますが、安全性は例外ですinsert/emplace

そもそも参照に新しい値を割り当てるにはどうすればよいでしょうか?

基本的に、非参照へ割り当てと同じです。const

int i = 5;
int &j = i;
j = 30;
i == 30; //This is true.
于 2016-08-27T02:29:12.073 に答える