Bul*_*net 12 c++ language-lawyer
这是过载(4)在这里
在“异常”部分中,重载2、3、5、6(具有pos1和/或pos2参数)被命名为throwing std::out_of_range。
重载(4)没有“ pos”参数,但未标记noexcept。
是否抛出该结果取决于实现?
在GCC 7的libstdc ++中,它调用char_traits<char>::length和char_traits<char>::compare。这些似乎无法抛出,但没有标记noexcept。
除了析构函数、交换函数、移动构造函数和移动赋值运算符之外,该标准noexcept仅在函数具有宽契约时才标记该函数,即它没有先决条件。此重载要求参数是一个以 null 结尾的字符串,因此标准不会将其标记为noexcept.
N3248中指定了有理数:
标记的功能
noexcept难以测试当一个函数被标记为 时,
noexcept就不可能通过抛出异常来标记测试失败,特别是在测试驱动程序中。一个常见的示例是验证函数入口前提条件的代码:Run Code Online (Sandbox Code Playgroud)T& std::vector<T>::front() noexcept { assert(!this->empty()); return *this->data(); }当验证来自测试驱动程序的此类防御性检查时,合理的方法是注册一个断言处理程序,该处理程序抛出一个定义良好的违反先决条件的异常,测试驱动程序捕获该异常以确保适当的确实
assert就位。...
现在我们可能会争辩说,当 为空时,调用合同外的函数
vector是未定义的行为,因此我们不应该期望任何保证。问题是库指定了未定义的行为;对于编译器来说,这段代码是完美定义的,如果assert抛出异常,程序必须以明确指定的方式终止,从而阻碍测试驱动程序。请注意,这里的问题不是我们使用断言来查找我们自己的库实现中的错误,而是错误地调用我们的库的用户代码中的错误。如果我们取消测试这些防御性断言的能力,我们可能会弄错它们,从而使我们的用户面临犯下比传播意外异常更严重的错误的风险。
顺便说一句,由于[res.on.exception.handling]/5:
实现可以通过添加非抛出异常规范来加强非虚函数的异常规范。
...libstdc++并且libc++可以自由地标记此过载noexcept。