代码之家  ›  专栏  ›  技术社区  ›  jma

C++中赋值,尽管右侧出现异常。

  •  70
  • jma  · 技术社区  · 6 年前

    我有一些(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] 创建(并分配一个空集)。

    这不是我所期望的:我期望他们以同样的方式工作。

    3 回复  |  直到 6 年前
        1
  •  96
  •   cat    6 年前

    在C++17之前,赋值运算符的左侧和右侧之间没有排序。

    在C++17中,首次引入显式排序(首先计算右侧)。

    这意味着评估顺序是 未指明 ,这意味着由实现按照所需的顺序执行求值,在本例中,它首先求值左侧。

    看到了吗 this evaluation order reference 更多细节(特别是第20点)。

        2
  •  17
  •   Micha Wiedenmann Lieven Keersmaekers    6 年前

    返回对映射到等价于的键的值的引用 键,如果该键不存在,则执行插入。

    junk[id] GetStuff() 投掷。注意,在C++14中,这些事情发生的顺序是用不同的编译器定义的实现 junk[id] = GetStuff(); 可能不会插入,如果 投掷。

        3
  •  12
  •   paddy    6 年前

    你误解了 operator[] 工作于 std::map

    它返回对映射项的引用。因此,您的代码首先在该位置插入一个默认项,然后调用 operator= 设置新值。

    std::map::insert (*):

    junk.insert(std::make_pair(id, GetStuff()));
    

    警告 insert 只有在 id 尚未映射。