【问题标题】:noexcept constructor of std::string_viewstd::string_view 的 noexcept 构造函数
【发布时间】:2020-05-28 09:30:30
【问题描述】:

根据the documentation,std::string_view 有一个构造函数,它接受一个const char * 和一个std::size_t,没有声明noexcept

constexpr basic_string_view(const CharT* s, size_type count);

另一方面,the documentation 还声明用户定义的字面量 operator""sv,在我看到的所有实现中,它是该构造函数的简单包装器,声明为 noexcept

constexpr std::string_view operator "" sv(const char* str, std::size_t len) noexcept;

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

【问题讨论】:

    标签: c++ c++17 noexcept user-defined-literals string-view


    【解决方案1】:

    对于构造函数

    constexpr basic_string_view(const CharT* s, size_type count);
    

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

    char c{'X'};
    std::string_view sv{&c, 100}; // oops
    

    因此,此函数没有wide contract(即接受所有输入),并且没有根据N3279 Conservative use of noexcept in the Library 标记noexcept — 将其标记为noexcept 将阻止库包含帮助用户发现错误的测试在他们的代码中(当然是在调试模式下)。 (有关更多信息,请参阅Can std::string::compare(const char*) throw an exception?。)


    另一方面,UDL 运算符

    constexpr std::string_view operator "" sv(const char* str, std::size_t len) noexcept;
    

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

    using std::string_literals;
    auto sv = "foo"sv;
    

    不存在传入无效指针值的可能性,因此运算符为noexcept。当然,你可以直接调用带有无效值的操作符,但这不是标准库应该处理的问题。

    【讨论】:

    • @bolov 将其标记为noexcept 将阻止库进行调试模式测试。这就是 N3279 的最初理由。您可以参考stackoverflow.com/a/56974315/9716597了解更多信息。
    • 你是对的。很好地包含了这两种资源。
    猜你喜欢
    • 2022-01-03
    • 2020-10-12
    • 2019-12-09
    • 2023-04-08
    • 2016-05-04
    • 2011-11-29
    • 2023-03-28
    • 1970-01-01
    • 2021-01-23
    相关资源
    最近更新 更多