45

私はstd::mapこのようなものを持っています:

map<wstring,int> Scores;

プレイヤーの名前とスコアを保存します。誰かがスコアを取得したとき、私は単純に次のことを行います。

Scores[wstrPlayerName]++;

キーを持つ要素がマップにない場合、要素はwstrPlayerName作成されますが、増分の前にゼロまたはnullに初期化されますか、それとも未定義のままですか?

インクリメントする前に、要素が毎回存在するかどうかをテストする必要がありますか?

プリミティブ型のものは作成時に常に未定義だと思っていたので、疑問に思いました。

私が次のようなものを書いた場合:

int i;
i++;

コンパイラは、iが未定義であり、プログラムを実行すると通常はゼロではないことを警告します。

4

4 に答える 4

64

operator[] は次のようになります。

Value& map<Key, Value>::operator[](const Key& key);

マップにまだないキーで呼び出すと、 Valueの新しいインスタンスをデフォルトで構築し、渡したキーの下のマップに配置し、それへの参照を返します。この場合、次のものがあります。

map<wstring,int> Scores;
Scores[wstrPlayerName]++;

ここでの値はintで、 int()で初期化したかのように、int はデフォルトで 0 として構築されます。他のプリミティブ型も同様に初期化されます ( double ()long()bool()など)。

最後に、コードは新しいペア (wstrPlayerName, 0) をマップに配置し、次に int への参照を返します。これをインクリメントします。したがって、要素を 0 から開始する場合は、要素がまだ存在するかどうかをテストする必要はありません。

于 2009-02-03T17:11:36.970 に答える
5

インクリメントする前にアイテムが存在するかどうかをテストしないでください。[] 演算子は、他の人が言ったように、必要なことを正確に行います。

しかし、デフォルトで構築された値がうまくいかない場合はどうでしょうか? あなたの場合、要素が既に存在するかどうかを確認する最良の方法は、要素を挿入することです。insertメンバー関数 forはstd::mapa を返しますstd::pair<iterator, bool>。挿入が成功するか失敗するかにかかわらず、ペアの最初の要素は目的のオブジェクト (新しいオブジェクト、または既に存在していたオブジェクト) を指します。その後、必要に応じてその値を変更できます。

于 2009-02-03T17:30:43.827 に答える
1

初期化のルールを確認してください。

セクション4.9.5C++ProgLangまたはC++stdbookの初期化を参照してください。変数がローカル、静的、ユーザー定義、またはconstのデフォルトの初期化のいずれであるかに応じて、初期化が発生する可能性があります。

この場合、intはPOD(Plain old Datatype)と呼ばれます。自動(ヒープ/ローカル変数で作成)POD変数はデフォルトで初期化されません。したがって、上記の「i」の値はゼロにはなりません。

ヒープで定義する場合は、常にPODを初期化する習慣をつけてください。int()を使用して値を初期化することもできます。

于 2009-02-03T17:49:44.693 に答える