std::set::find异常保证
std::set::find exception guarantees
我目前正在编写异常安全代码,我的设计不需要对set::find方法。我认为comparator对象总是成功的。这是否意味着set::find方法总是成功的?
根据http://en.cppreference.com/w/cpp/container/set/erase,set::erase方法,具有相同的假设,应该总是成功的,也许其中有一个发现(那么它显然值得在文档中发表评论!)
问题的直接来源是,我需要检查元素是否在集合中,并将其从集合中删除——所有这些都没有抛出保证(它在catch块中)。
std::set::find
:
返回值
迭代到键为
key
的元素。如果找不到这样的元素,则返回over-the-end(请参见end())迭代器。
文档和C++标准都没有明确列出任何异常安全保证。然而,此处适用std::set::erase
的相同规则(§23.2.4.1例外安全保证[相关要求除外]):
erase(k)
不会抛出异常,除非该异常是由容器的Compare
对象(如果有)抛出的。
本质上,除非Compare
对象抛出异常,否则std::set::find
不会抛出。Bjarne Stroustrup在C++编程语言特别版-附录E:中有以下几点要说
幸运的是,谓词很少做任何可能引发异常的事情。但是,在考虑异常安全性时,必须考虑用户定义的
<
、==
和!=
谓词。
如果您没有提供任何用户定义的谓词,您可以假设std::set::find
没有抛出异常。如果是,则应将它们标记为noexcept
,以便在您的场景中安全工作。
C++11§23.2.4.1异常安全保证[associal.reqmts.except]列出了关联容器(包括set
)的所有异常安全要求,但没有提及find
。所以不,标准并不能保证find
永远不会抛出。
在没有未定义的行为并且假设有一个非抛出比较器的情况下,我发现C++标准库的实现极不可能存在,它将从set::find
抛出异常。我个人认为(a)将set::find
封装在noexcept
转发函数中,这样如果发生这种"不可能"的事情,程序就会崩溃,或者(b)将特定的set::find
调用封装在中
auto it = foo.end();
try {
it = foo.find(bar);
} catch(...) {}
并简单地将异常处理为"未找到">
请注意,关联容器的排序关系是未定义行为的一个容易被忽视的来源:§23.2.4/2要求排序关系在关键元素上诱导严格的弱排序(如§25.4所述)。使用而非严格弱排序的排序关系实例化的关联容器没有定义的行为,其一个可能的结果是从find
引发异常。
- 处理多个异常集合的C++方法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 我在c++代码中生成了一个运行时#3异常
- 孤立代码块在结构中引发异常
- C++中的赋值发生,尽管右侧出现异常
- 从构造函数抛出异常时如何克服内存泄漏
- 异常属于C++中的线程还是进程
- 当类定义不可见时捕获异常
- OpenMP卸载说'fatal error: could not find accel/nvptx-none/mkoffload'
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- 为什么异常不退出程序?
- 使用.find函数在c++中查找字符和另一个字符之间的大小
- 为什么我应该在异常处理中使用std::cerr而不是std::cout
- 如何修复链表类实现的未处理异常0xDDDDDDDD
- 关于:C++中异常对象的范围:为什么我没有得到副本?
- 是什么导致了Unity 3D中的"错误线程异常"?
- 如何将strftime中的格式错误作为异常捕获
- 创建具有 new in 函数和"this is nullptr"异常的对象
- 在 QVector<std::unique_ptr 上使用 std::find<Type>>
- std::set::find异常保证