为什么这两个 std::string find() 函数被声明为 noexcept?

Why those two std::string find() functions are declared as noexcept?

根据[string.find#1.2] and [string.find#1.3]

Each member function of the form

  • constexpr size_type F(const charT* s, size_type pos) const;

has effects equivalent to: return F(basic_­string_­view<charT, traits>(s), pos);

Each member function of the form

  • constexpr size_type F(const charT* s, size_type pos, size_type n) const;

has effects equivalent to: return F(basic_­string_­view<charT, traits>(s, n), pos);

那两个 find 函数没有声明为 noexcept,但是三个编译器供应商的 all 没有遵守规则,他们只是将其实现为 noexcept .

这背后的原因是什么?

好的,我找到答案了。

根据 [res.on.exception.handling]:

An implementation may strengthen the exception specification for a non-virtual function by adding a non-throwing exception specification.

所以他们可以自由标记这个过载noexcept。感谢您的关注。

这就是所谓的拉科斯法则。参见 N3248。规则是,如果函数有前提条件,则不应将其标记为 noexcept,因为如果实现选择这样做,它会阻止实现检查前提条件并在验证时抛出异常。

在这种情况下,find(s, pos, n) 等同于 find(string_view(s, n), pos)string_view(s, n) 构造的前提条件是 s 是长度至少为 n 的有效字符串。所以一个实现 可以 尝试以某种方式验证它并在失败时抛出异常。

但是 none 的实现实际上试图验证这一点,因此他们没有采取可能抛出前提条件违规的自由,而是简单地将这些函数标记为 noexcept。他们被允许从 [res.on.exception.handling]:

开始

An implementation may strengthen the exception specification for a non-virtual function by adding a non-throwing exception specification.


Library Evolution 最近接受了 P1656,这基本上恢复了 Lakos 规则。