Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用自定义比较器时std::map异常安全吗?_C++_Dictionary_Stdmap_Exception Safety - Fatal编程技术网

C++ 使用自定义比较器时std::map异常安全吗?

C++ 使用自定义比较器时std::map异常安全吗?,c++,dictionary,stdmap,exception-safety,C++,Dictionary,Stdmap,Exception Safety,如果自定义比较器在重新平衡期间抛出异常,std::map将做什么?显然,它应该记住之前的所有转向,并将所有东西恢复到其原始状态。这是真的吗?参见[associative.reqmts.except]: 对于关联容器,noclear()函数不会引发异常erase(k)不会引发异常,除非容器的Compare对象(如果有)引发该异常 对于关联容器,如果从插入单个元素的insert或emplace函数中的任何操作引发异常,则插入无效 对于关联容器,除非容器的Compare对象(如果有)的交换引发异常,否

如果自定义比较器在重新平衡期间抛出异常,
std::map
将做什么?显然,它应该记住之前的所有转向,并将所有东西恢复到其原始状态。这是真的吗?

参见[associative.reqmts.except]:

对于关联容器,no
clear()
函数不会引发异常
erase(k)
不会引发异常,除非容器的
Compare
对象(如果有)引发该异常

对于关联容器,如果从插入单个元素的
insert
emplace
函数中的任何操作引发异常,则插入无效

对于关联容器,除非容器的
Compare
对象(如果有)的交换引发异常,否则没有
swap
函数引发异常


因此,您基本上是对的(在单元素插入的情况下),但这并不意味着容器必须“记住所有以前的步骤”才能“将所有内容恢复到其原始状态”。假设关联容器是使用自平衡二叉搜索树实现的(我不确定是否还有其他可能性),比较只是为了沿着树向下走,找到必须插入新节点的位置。如果在这个过程中通过异常退出比较,那么树还没有被修改,所以容器所要做的就是释放此时为新元素分配的内存(如果有的话)。接下来的重新平衡步骤无法生成异常,因为它只涉及执行一系列树旋转和更新内部簿记数据,例如节点是红色还是黑色。

这在CPPCON的一次演讲中有所介绍。现在找不到,但我稍后回家后会尝试查找。引用的文本仅表示,如果引发异常,则插入无效。如果
erase(k)
抛出异常,它不会说明容器处于什么状态。“钥匙是否被取下了?”凯文很不幸,它似乎没有说。但是按照同样的逻辑,如果发生异常,似乎不可能删除元素,因为容器找不到节点。