当前位置: 首页 > 知识库问答 >
问题:

尽管右侧出现异常,C中的赋值仍会发生

潘彦
2023-03-14

我有一些(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原则?

共有3个答案

汪深
2023-03-14

您误解了操作符[]std::map

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

要使其按预期方式工作,您需要使用std::map::insert(*):

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

警告:如果< code>id尚未映射,则< code>insert将只添加值。

夹谷衡
2023-03-14

std::map::operator[]

返回对映射到与 key 等效的键的值的引用,如果此类键尚不存在,则执行插入。

junk[id]导致上述插入,之后已经发生GetStuff()抛出。请注意,在C 14中,这些事情发生的顺序是实现定义的,因此使用不同的编译器您的junk[id]=GetStuff();如果GetStuff()抛出,可能不会进行插入。

宋康安
2023-03-14

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

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

这意味着评估顺序未指定,这意味着由实现按照它想要的顺序执行评估,在这种情况下,它首先评估左侧。

有关更多详细信息(特别是第20点),请参见本评估订单参考。

 类似资料:
  • 我有一个由多个线程操作的ArrayList,由于ArrayList没有同步,所以无法工作。按照教授的指示,我把列表换成了向量。向量是同步的,但我抛出了与同步相关的异常。 为什么会发生这种情况,我如何避免代码中的并发异常?我不想只是玩玩,直到有东西起作用,我想做最好的事情。谢谢! 例外情况: 代码:

  • 问题内容: 这个问题源于-其他解包概述,据我所知,它存在于Python 3.5中(并且没有反向移植到)。具体来说,在“ 缺点 ”部分中,注意以下几点: 虽然原因是一, ,原因是一个。这样做的原因可能会使不熟悉该结构的人感到困惑。 对于第一种情况,确实确实存在: 在第二种情况下,创建了: 不熟悉这个概念,我很困惑。谁能解释这种行为?加星标的表情是否会根据其所在的侧面而有所不同? 问题答案: 当还考虑

  • 问题内容: 在我用Swift编写的SpriteKit iOS游戏中,播放非常短的声音(约0.5秒)会产生打ic(如滞后)。在其他问题中,我读到我应该发出声音,就像以前那样。 我什至使用变量()在播放之前检查声音是否准备就绪。每当播放完()时,我也会重新准备声音。以下是代码的相关部分: 我不知道我在哪里犯了错误。我感觉我已经尝试了所有方法(包括但不限于:仅准备一次,在播放后立即准备,不使用变量,而只

  • 我有一个类,它具有应该被注入的字段。 并且有接口仅由类实现,具有的。 当我尝试启动SpringBootApplication时,会抛出。 为什么接口注册为bean的一个,即使它没有注释,也没有包含任何bean配置? 我发现,如果我不使用作为,一切都很好。 有什么想法吗?

  • 我试图读取一个CSV文件,然后根据该CSV文件创建一个新的对象。我可以用SuperCSV库成功地做到这一点,但是如果发生错误(例如特定的单元格为null),它会抛出一个错误(如预期的那样)。我试图在ArrayList中收集所有错误,但现在第一个异常时一切都会停止。如何使SuperCSV CsvBeanReader继续到下一行,即使处理器出现错误?我在try/catch块中有循环条件。代码如下:

  • 摘自:https://docs.microsoft.com/en-us/azure/cosmos-db/create-graph-dotnet 我在 .wait() 部分遇到异常: 代码: