Title
span's Container constructors need another constraint
Status
c++20
Section
[span.cons]
Submitter
Stephan T. Lavavej

Created on 2018-04-12.00:00:00 last changed 38 months ago

Messages

Date: 2018-11-12.05:21:03

Proposed resolution:

This wording is relative to N4741.

  1. Edit [span.cons] as indicated:

    template<class Container> constexpr span(Container& cont);
    template<class Container> constexpr span(const Container& cont);
    

    -14- Requires: [data(cont), data(cont) + size(cont)) shall be a valid range. If extent is not equal to dynamic_extent, then size(cont) shall be equal to extent.

    -15- Effects: Constructs a span that is a view over the range [data(cont), data(cont) + size(cont)).

    -16- Postconditions: size() == size(cont) && data() == data(cont).

    -17- Throws: What and when data(cont) and size(cont) throw.

    -18- Remarks: These constructors shall not participate in overload resolution unless:

    1. (18.?) — extent == dynamic_extent,

    2. (18.1) — Container is not a specialization of span,

    3. (18.2) — Container is not a specialization of array,

    4. […]

Date: 2018-11-12.05:21:03

[ 2018-11 San Diego Saturday ]

LEWG said that they're fine with the proposed resolution. Status to Tentatively Ready.

Date: 2018-06-12.14:27:03

[ 2018-06 Rapperswil Thursday issues processing ]

Status to LEWG. Should this be ill-formed, or fail at runtime if the container is too small? Discussion on the reflector here.

Date: 2018-04-24.00:00:00

[ 2018-04-24 Priority set to 1 after discussion on the reflector. ]

Date: 2018-04-12.00:00:00

When I overhauled span's constructor constraints, I was careful about the built-in array, std::array, and converting span constructors. These types contain bounds information, so we can achieve safety at compile-time by permitting implicit conversions if and only if the destination extent is dynamic (this accepts anything by recording the size at runtime) or the source and destination extents are identical. However, I missed the fact that the Container constructors are the opposite case. A Container (e.g. a vector) has a size that's known only at runtime. It's safe to convert this to a span with dynamic_extent, but for consistency and safety, this shouldn't implicitly convert to a span with fixed extent. (The more verbose (ptr, count) and (first, last) constructors are available to construct fixed extent spans from runtime-length ranges. Note that debug precondition checks are equally possible with the Container and (ptr, count)/(first, last) constructors. The issue is that implicit conversions are notoriously problematic, so they should be permitted only when they are absolutely known to be safe.)

History
Date User Action Args
2021-02-25 10:48:01adminsetstatus: wp -> c++20
2019-02-26 17:40:23adminsetstatus: voting -> wp
2019-01-21 04:50:04adminsetstatus: ready -> voting
2018-11-12 05:21:03adminsetmessages: + msg10218
2018-11-12 05:21:03adminsetstatus: lewg -> ready
2018-06-12 04:35:59adminsetmessages: + msg9912
2018-06-12 04:35:59adminsetstatus: new -> lewg
2018-05-05 12:43:31adminsetmessages: + msg9835
2018-04-22 14:47:32adminsetmessages: + msg9821
2018-04-12 00:00:00admincreate