std::string_view 的 noexcept 构造函数

Gio*_*ani 6 c++ user-defined-literals noexcept string-view c++17

根据文档, std::string_view 有一个带有 aconst char *和 a的构造函数std::size_t,但未声明noexcept

constexpr basic_string_view(const CharT* s, size_type count);
Run Code Online (Sandbox Code Playgroud)

另一方面,文档还声明了用户定义的文字operator""sv,在我见过的所有实现中都是该构造函数的简单包装器,已声明noexcept

constexpr std::string_view operator "" sv(const char* str, std::size_t len) noexcept;
Run Code Online (Sandbox Code Playgroud)

你知道这种差异的原因吗?构造函数什么时候可以抛出?

L. *_* F. 6

对于构造函数

constexpr basic_string_view(const CharT* s, size_type count);
Run Code Online (Sandbox Code Playgroud)

您可以将任何内容作为字符串传递:

char c{'X'};
std::string_view sv{&c, 100}; // oops
Run Code Online (Sandbox Code Playgroud)

因此,这个函数没有广泛的契约(即接受所有输入),并且没有noexcept根据库中的N3279 保守使用noexcept进行标记- 标记它noexcept会阻止库包含测试以帮助用户发现代码中的错误(在调试中)当然是模式)。(有关详细信息,请参阅std::string::compare(const char*) 能否引发异常? )。


另一方面,UDL 运算符

constexpr std::string_view operator "" sv(const char* str, std::size_t len) noexcept;
Run Code Online (Sandbox Code Playgroud)

通常在翻译文字时由语言调用:

using std::string_literals;
auto sv = "foo"sv;
Run Code Online (Sandbox Code Playgroud)

不可能传入无效的指针值,因此运算符为noexcept。当然,您可以直接使用无效值调用运算符,但这不是标准库应该处理的问题。