如果自定义比较器在重新平衡期间抛出异常,std::map
将怎么办?显然,它应该记住之前的所有回合,并将所有内容返回到原始状态。这是真的吗?
参见[associative.reqmt .except]:
对于关联容器,没有
clear()
函数抛出异常。erase(k)
不会抛出异常,除非该异常是由容器的Compare
对象(如果有的话)抛出的。对于关联容器,如果在
insert
或emplace
函数中插入单个元素的操作引发异常,则插入无效。对于关联容器,除非交换容器的
Compare
对象(如果有的话),否则swap
函数不会抛出异常。
所以你基本上是对的(在插入单个元素的情况下),但这并不意味着容器必须"记住之前的所有回合"。为了"把一切都恢复到原来的状态"。假设关联容器是使用自平衡二叉搜索树实现的(我不确定是否有其他可能性),进行比较只是为了沿着树向下走,找到必须插入新节点的位置。如果在此过程中通过异常退出比较,则树尚未被修改,因此容器所要做的就是释放此时为新元素分配的内存(如果有的话)。接下来的再平衡步骤不会产生异常,因为它只涉及执行一堆树旋转和更新内部簿记数据,例如节点是红色还是黑色。