3100. Unnecessary and confusing "empty span" wording

Section: 23.7.2.2.2 [span.cons] Status: C++20 Submitter: Stephan T. Lavavej Opened: 2018-04-12 Last modified: 2021-02-25

Priority: 0

View all other issues in [span.cons].

View all issues with C++20 status.

Discussion:

The span constructors have wording relics that mention an "empty span". It's unnecessary (the behavior is fully specified by the postconditions), but I left it there because I thought it was harmless. It was later pointed out to me that this is actually confusing. Talking about an "empty span" implies that there's just one such thing, but span permits empty() to be true while data() can vary (being null or non-null). (This behavior is very useful; consider how equal_range() behaves.)

To avoid confusion, the "empty span" wording should simply be removed, leaving the constructor behavior unchanged. Editorially, there's also a missing paragraph number.

[ 2018-04-24 Moved to Tentatively Ready after 6 positive votes on c++std-lib. ]

[2018-06 Rapperswil: Adopted]

Proposed resolution:

This wording is relative to N4741.

  1. Edit 23.7.2.2.2 [span.cons] as indicated:

    constexpr span() noexcept;
    

    -1- Effects: Constructs an empty span.

    -2- Postconditions: size() == 0 && data() == nullptr.

    -3- Remarks: This constructor shall not participate in overload resolution unless Extent <= 0 is true.

    constexpr span(pointer ptr, index_type count);
    

    -4- Requires: [ptr, ptr + count) shall be a valid range. If extent is not equal to dynamic_extent, then count shall be equal to extent.

    -5- Effects: Constructs a span that is a view over the range [ptr, ptr + count). If count is 0 then an empty span is constructed.

    -6- Postconditions: size() == count && data() == ptr.

    -?- Throws: Nothing.

    constexpr span(pointer first, pointer last);
    

    -7- Requires: [first, last) shall be a valid range. If extent is not equal to dynamic_extent, then last - first shall be equal to extent.

    -8- Effects: Constructs a span that is a view over the range [first, last). If last - first == 0 then an empty span is constructed.

    -9- Postconditions: size() == last - first && data() == first.

    -10- Throws: Nothing.