マップに要素を挿入するとき、推奨される方法は何だろうと思っていました。したほうがいい
map[key] = value;
または
map.insert(std::pair<key_type, value_type>(key, value));
次の簡単なテストを行いました。
#include <map>
#include <string>
#include <iostream>
class Food {
public:
Food(const std::string& name) : name(name) { std::cout << "constructor with string parameter" << std::endl; }
Food(const Food& f) : name(f.name) { std::cout << "copy" << std::endl; }
Food& operator=(const Food& f) { name = f.name; std::cout << "=" << std::endl; return *this; }
Food() { std::cout << "default" << std::endl; }
std::string name;
};
int main() {
std::map<std::string, Food> m0;
/*
1) constructor with string parameter
2) copy
3) copy
4) copy
*/
m0.insert(std::pair<std::string, Food>("Key", Food("Ice Cream")));
/*
1) constructor with string parameter
2) default
3) copy
4) copy
5) =
*/
// If we do not provide default constructor.
// C2512: 'Food::Food' : no appropriate default constructor available
m0["Key"] = Food("Ice Cream");
}
insert
を使用することで、より少ない値の関数呼び出しが関与することに気付きます。では、insert
を使用することをお勧めしますか?map[key] = value
ウェイが使用されているのに、なぜデフォルトのコンストラクターが必要なのですか?insert
は既存のキーと値のペアを上書きしませんが、map[key] = value
は上書きします。しかし、両方から選択しようとするとき、これが私が考慮に入れる唯一の要因ですか?
どう?
insert
は推奨される方法ではありません-マップに挿入する方法の1つです。 operator[]
との違いは、insert
が要素がマップに挿入されているかどうかを判断できることです。また、クラスにデフォルトのコンストラクタがない場合、insert
を使用する必要があります。operator[]
にはデフォルトのコンストラクタが必要です。そうでない場合は、デフォルトのコンストラクターを使用して作成し、参照(またはconst参照)を返します。マップコンテナでは重複したキー値は許可されないため、挿入操作では、挿入された各要素について、同じキー値を持つコンテナに別の要素が既に存在するかどうかがチェックされます。仕方。
新しい要素を挿入する場合は、insert
を使用します。 insert
は既存の要素を上書きしません。以前に存在していた要素がなかったことを確認できます。
if ( !myMap.insert( std::make_pair( key, value ) ).second ) {
// Element already present...
}
既存の要素を上書きする場合は、[]
を使用します。
myMap[ key ] = value;
assert( myMap.find( key )->second == value ); // post-condition
このフォームは、既存のエントリを上書きします。
引用するには:
マップコンテナでは重複したキー値は許可されないため、挿入操作では、挿入された各要素について、同じキー値を持つコンテナに別の要素が既に存在するかどうかがチェックされます。仕方。
したがって、キーがすでに存在する場合、挿入は値を変更しません。[] operator
は変更されます。
編集:
これは別の最近の質問を思い出させます-[] operator
の代わりにat()
を使用してベクターから値を取得する理由。明らかに、[] operator
がそうではないのに対し、インデックスが範囲外の場合、at()
は例外をスローします。このような状況では、すべての詳細が提供されるため、関数のドキュメントを参照するのが常に最善です。しかし、一般に、まったく同じことを行う2つの関数/演算子はありません(または少なくともそうすべきではありません)。
私の推測では、内部では、insert()
は最初にエントリをチェックし、その後は[] operator
を使用します。
map[key] = value
は、構文を簡単にするために提供されています。読み書きが簡単です。
デフォルトのコンストラクターが必要な理由は、map[key]
が割り当ての前に評価されるためです。キーがマップに存在しなかった場合、新しいキーが(デフォルトのコンストラクターで)作成され、その参照がoperator[]
から返されます。