【问题标题】:Is std::map exception safe with custom comparator?使用自定义比较器,std::map 异常是否安全?
【发布时间】:2021-02-19 19:12:33
【问题描述】:

如果自定义比较器在重新平衡期间抛出异常,std::map 会做什么?显然,它应该记住所有先前的回合并将所有内容恢复到原始状态。是真的吗?

【问题讨论】:

  • 这在 CPPCON 的一次演讲中有所体现。现在找不到,等我回家再找。

标签: c++ dictionary stdmap exception-safety


【解决方案1】:

参见[associative.reqmts.except]:

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

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

对于关联容器,swap 函数不会引发异常,除非该异常是由容器的 Compare 对象(如果有)的交换引发的。

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

【讨论】:

  • 引用的文字只是说如果抛出异常,插入没有效果。如果erase(k) 抛出异常,它不会说明容器处于什么状态。密钥是否被移除?
  • @Kevin 好吧,不幸的是,它似乎没有说。但是按照同样的逻辑,如果发生异常,元素似乎不可能被移除,因为容器找不到节点。
猜你喜欢
  • 1970-01-01
  • 2017-12-26
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-20
  • 1970-01-01
相关资源
最近更新 更多