この質問に答えた後、問題のコードが未定義の動作であるかどうかについて長い議論がありました。コードは次のとおりです。
std::map<string, size_t> word_count;
word_count["a"] = word_count.count("a") == 0 ? 1 : 2;
まず第一に、これが少なくとも特定されていないことは確立されていました。結果は、割り当てのどちら側が最初に評価されるかによって異なります。私の回答では、結果として得られた 4 つのケースのそれぞれについて、どちらの側が最初に評価されるか、および要素がこれより前に存在するかどうかの要因を追跡しました。
同様に出てきた短い形式がありました:
(x = 0) = (x == 0) ? 1 : 2; //started as
(x = 0) = (y == "a") ? 1 : 2; //changed to
私はそれがもっとこのようなものだと主張しました:
(x = 0, x) = (x == 0) ? 1 : 2; //comma sequences x, like [] should
最終的に、私にとってうまくいくと思われる例を見つけました:
i = (++i,i++,i); //well-defined per SO:Undefined Behaviour and Sequence Points
元に戻って、簡単に理解できるように、関連する関数呼び出しに分割しました。
operator=(word_count.operator[]("a"), word_count.count("a") == 0 ? 1 : 2);
^ inserts element^ ^reads same element
|
assigns to element
word_count["a"]
が存在しない場合は、間に順序付けなしで 2 回割り当てられると主張されました。私が真実だと思っていた2つのことが実際にあった場合、私は個人的にそれがどのように起こるかわかりませんでした:
サイドが評価のために選ばれるとき、反対側が開始する前に、サイド全体が評価されなければなりません。
word_count["a"] = 1 などの構成要素は、要素が挿入されてから割り当てられた場合でも、明確に定義された動作を示します。
これらの 2 つのステートメントは本当ですか? 最終的に、それは実際には未定義の動作ですか? もしそうなら、なぜ 2 番目のステートメントが機能するのですか (機能すると仮定して)? 2 番目が false の場合、myMap[i]++;
世界中のすべての s は形式が正しくないと思います。
役立つリンク:未定義の動作とシーケンス ポイント