c++exceptionstlnoexcept

Is std::span constructor missing noexcept?


According to cppreference constructor (2) of std::span is defined as

template< class It >
explicit(extent != std::dynamic_extent)
constexpr span( It first, size_type count );

with its exceptions listed as 2) Throws nothing.

If this constructor "throws nothing" then why is it even listed under exceptions and why is the constructor not marked noexcept?


Solution

  • That's because this constructor has preconditions. From the standard:

    template<class It>
    constexpr explicit(extent != dynamic_extent) span(It first, size_type count);

    Constraints: Let U be remove_­reference_­t<iter_­reference_­t>.

    • It satisfies contiguous_­iterator.
    • is_­convertible_­v<U()[], element_­type()[]> is true.
      [Note 1: The intent is to allow only qualification conversions of the iterator reference type to element_­type. — end note]

    Preconditions:

    • [first, first + count) is a valid range.
    • It models contiguous_­iterator.
    • If extent is not equal to dynamic_­extent, then count is equal to extent.

    Effects: Initializes data_­ with to_­address(first) and size_­ with count.

    Throws: Nothing.

    Functions with preconditions that "throw nothing" aren't marked noexcept because undefined behavior can occur if these preconditions aren't fulfilled. For example, std::vector::front isn't marked noexcept even though there is no way it would throw, but calling it on an empty vector is undefined behavior.

    Here is a paper about it: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1656r1.html