c++c++17noexceptuser-defined-literalsstring-view

noexcept constructor of std::string_view


According to the documentation, std::string_view has a constructor that takes a const char * and a std::size_t, that is not declared noexcept:

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

On the other hand, the documentation states also that the user defined literal operator""sv, that in all the implementations I've seen is a simple wrapper to that constructor, is declared noexcept:

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

Do you know the reason of this difference? When is that the constuctor can throw?


Solution

  • For the constructor

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

    you can pass anything as the string:

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

    Therefore, this function does not have a wide contract (i.e., accepts all inputs), and is not marked noexcept per N3279 Conservative use of noexcept in the Library — marking it noexcept would prevent libraries from including tests to help users discover bugs in their code (in debug mode, of course). (See Can std::string::compare(const char*) throw an exception? for more information.)


    On the other hand, the UDL operator

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

    is usually called by the language when translating a literal:

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

    There is no possibility of invalid pointer values passed in, so the operator is noexcept. Of course, you can directly invoke the operator with an invalid value, but that's not the kind of problem that the standard library is supposed to handle.