span
's Container
constructors need another constraintSection: 23.7.2.2.2 [span.cons] Status: C++20 Submitter: Stephan T. Lavavej Opened: 2018-04-12 Last modified: 2021-02-25
Priority: 1
View all other issues in [span.cons].
View all issues with C++20 status.
Discussion:
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.)
[2018-04-24 Priority set to 1 after discussion on the reflector.]
[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.
[2018-11 San Diego Saturday]
LEWG said that they're fine with the proposed resolution. Status to Tentatively Ready.
Proposed resolution:
This wording is relative to N4741.
Edit 23.7.2.2.2 [span.cons] as indicated:
template<class Container> constexpr span(Container& cont); template<class Container> constexpr span(const Container& cont);-14- Requires:
-15- Effects: Constructs a[data(cont), data(cont) + size(cont))
shall be a valid range.Ifextent
is not equal todynamic_extent
, thensize(cont)
shall be equal toextent
.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 whendata(cont)
andsize(cont)
throw. -18- Remarks: These constructors shall not participate in overload resolution unless:
(18.?) —
extent == dynamic_extent
,(18.1) —
Container
is not a specialization ofspan
,(18.2) —
Container
is not a specialization ofarray
,[…]