10

私が行った場合:

std::map<string, size_t> word_count;
size_t value = word_count.count("a") == 0 ? 1 : 2;
word_count["a"] = value;

予想どおり、word_count["a"] の最終値は 1 です。代わりに私がする場合:

std::map<string, size_t> word_count;
word_count["a"] = word_count.count("a") == 0 ? 1 : 2;

word_count["a"] の最終値は 2 です。なぜ!?

4

2 に答える 2

11

正式には、割り当てのどちらの側も最初に評価できます。どちらを決定するかは、実装次第です。word_countが含まれていない場合は"a"、挿入され、それへの左辺値参照が返されます。word_count含まれている場合は、後半部分のみが発生します。どちらの側が最初に評価されるかは不確実ですが、可能な実行を追跡できます。

左側を先に

要素が存在しません:

operator[]要素がまだ存在しないため、要素を挿入します。count()はそれを見つけて 1 を返すため、最終的には値 2 が割り当てられます。

要素が存在します:

operator[]既存の要素を返し、count()それを見つけて 1 を返すため、最終的に値 2 が割り当てられます。

右側が先

要素が存在しません:

count()は 0 を返すので、右辺から 1 を取得します。次に、"a"マップに挿入され、値 1 が割り当てられます。

要素が存在します:

count()は 1 を返すので、右側から 2 を取得します。次に、word_count["a"]がアクセスされ、2 が割り当てられます。

結論

要するに、これに頼ってやりたいことができるわけではないので、信頼できるものを使用したほうがよいのです。mrfontanini が良い提案をしてくれたので、少し編集します。

word_count["a"]++;
word_count["a"] = std::min(word_count["a"], 2);

最初の行は、それが挿入され、少なくとも 1 の値を持つことを保証します。2 番目の行は、この操作を繰り返し行う場合に備えて、その値を最大 2 に制限します。

ノート

この答えは、次の 2 つの点に基づいています。

  1. サイドが評価のために選ばれるとき、もう一方のサイドが開始する前に、サイド全体が評価されなければなりません。

  2. などword_count["a"] = 1の構成要素は、要素が挿入されてから割り当てられた場合でも、明確に定義された動作を示します。

これらが真実かどうかについては、以下でいくつかの議論と議論があります。もう少し公式にしました。

于 2013-04-06T21:07:57.057 に答える