这是重载(4)here
在“异常”部分中,重载2、3、5、6(具有pos1和/或pos2参数)被命名为抛出std::out_of_range
。
重载(4)没有“ pos”参数,但未标记为noexcept
。
是否抛出该结果取决于实现?
在GCC 7的libstdc ++中,它调用char_traits<char>::length
和char_traits<char>::compare
。这些似乎无法抛出,但没有标记为noexcept
。
答案 0 :(得分:1)
除析构函数,交换函数,移动构造函数和移动赋值运算符外,该标准仅在具有wide contract的情况下标记函数noexcept
,即没有先决条件。此重载要求参数是一个以空值结尾的字符串,因此标准不会将其标记为noexcept
。
有理在N3248中指定:
标记为
noexcept
的功能很难测试当一个函数标有
noexcept
时,就不可能标记测试失败, 特别是在测试驱动程序中,会引发异常。一个常见的例子是代码 可以验证输入函数的先决条件:T& std::vector<T>::front() noexcept { assert(!this->empty()); return *this->data(); }
验证测试驾驶员的这种防御性检查时,一种合理的方法是 注册一个引发明确定义的违反先决条件的异常的断言处理程序, 测试驱动程序捕获的内容,以确保确实存在适当的
assert
地方。...
现在我们可能会争辩说,当
vector
为 空,是未定义的行为,因此我们不应期望任何保证。问题在于该库正在指定未定义的行为。对于编译器,此代码是 定义明确,并且如果assert
引发异常,则程序必须终止 以明确的方式阻止测试驱动程序。请注意,这里的问题不是我们在使用断言来查找自己的错误 库实现,而是在错误地调用我们库的用户代码中。 如果我们取消测试这些防御性断言的能力,我们可能会弄错它们, 因此,与传播相比,我们的用户有犯更严重错误的风险 意外的异常。
顺便说一句,由于[res.on.exception.handling]/5:
实现可以通过添加非抛出异常规范来增强非虚函数的异常规范。
... libstdc++
和libc++
可以自由标记此重载noexcept
。