![](/img/trans.png)
[英]C++ comparison with an assignment expression be the right hand side expression
[英]Assignment in C++ occurs despite exception on the right side
我有一些(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)。
std :: map :: operator []
返回对该值的引用,该值映射到与键等效的键,如果该键尚不存在,则执行插入。
junk[id]
导致上述插入,此后已经发生GetStuff()
抛出。 请注意,在C ++ 14中,发生这些事情的顺序是由实现定义的,因此使用其他编译器,您的junk[id] = GetStuff();
如果GetStuff()
抛出,则可能不会执行插入GetStuff()
。
您误解了operator[]
在std::map
。
它返回对映射项的引用。 因此,您的代码首先是在该位置插入默认项,然后调用operator=
设置新值。
要按照您期望的方式工作,您需要使用std::map::insert
(*):
junk.insert(std::make_pair(id, GetStuff()));
注意 :如果id
尚未映射,则insert
将仅添加值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.