1. ホーム
  2. c++

C++の代入は右辺に例外があっても発生する

2023-11-30 06:12:26

質問

以下のような(C++14)コードがあります。

map<int, set<string>> junk;
for (int id : GenerateIds()) {
    try {
        set<string> stuff = GetStuff();
        junk[id] = stuff;
    } catch (const StuffException& e) {
        ...
    }
}

これは有効です。時々 GetStuff() は例外を投げますが、それはうまくいきます。なぜなら、もし例外が起きたら、そのときはジャンクマップに値を入れたくないからです。

しかし、最初はこれをループの中に書いていたのですが、これはうまくいきません。

junk[id] = GetStuff();

より正確には GetStuff() は例外を投げます。 junk[id] は作成されます(そして空集合が割り当てられます)。

これは私が期待するものではありません。私はこれらが同じように機能することを期待しています。

私が誤解しているC++の原則があるのでしょうか?

どのように解決するのですか?

C++17 以前では、代入演算子の左辺と右辺の間に順序はありませんでした。

明示的な順序付けが導入されたのは C++17 が初めてです(右辺が先に評価されます)。

つまり、評価順序は 不特定 であることを意味します。つまり、評価を行う順番は実装次第であり、この場合は左辺を先に評価します。

参照 この評価順序のリファレンス を参照してください(特にポイント20)。