Skip to content

Add initializer_list constructor for span<const T> (P4190R0)#9

Open
SamareshSingh wants to merge 3 commits intomainfrom
initializer-list-ctor-p4190
Open

Add initializer_list constructor for span<const T> (P4190R0)#9
SamareshSingh wants to merge 3 commits intomainfrom
initializer-list-ctor-p4190

Conversation

@SamareshSingh
Copy link
Copy Markdown
Collaborator

@SamareshSingh SamareshSingh commented Apr 26, 2026

Implements the C++29 reinstatement of span's initializer_list constructor, the same one P2447R6 added for C++26 and P4144R1 had to revert.

The two key constraints (per P4190R0):

  • is_const_v<element_type> : only span<const T> accepts an il, since the il's underlying array is a temporary, and the const-element rule is what makes the ctor sound.
  • same_as<value_type, InitListValueType> : exact element-type match, no implicit conversions. This is the whole point of the redesign: span<const bool>{ptr, size} no longer silently grabs this overload via two pointer-to-bool conversions, which was the regression that got the C++26 version reverted.

Implementation notes:

  • A dummy class T_ = ElementType template parameter keeps the is_const_v check dependent on a function-template parameter. Without it the check would be non-dependent and produce a hard error when instantiating span<int>, instead of just SFINAE-ing the il ctor out of overload resolution. Same trick the existing default constructor uses with std::size_t E = Extent.
  • The remaining -Winit-list-lifetime warning is informational and it points out the lifetime caveat the user takes on for any span over a temporary, which is exactly the design.

Added below six new tests:

  • Dynamic and fixed-extent construction from a braced-init-list, written in the function-call idiom because the il's underlying array is a full-expression temporary (using the span on a later line is UB).
  • span<const bool> from {true, false, true}, the case the original C++26 version already handled, has to keep working.
  • Named std::initializer_list<int> variable extends the underlying array's lifetime to block scope, lets the span outlive the construction expression.
  • span<const bool>(ptr, n) still resolves to the It+count ctor, not the il ctor. This is the exact regression P4144R1 reverted; locking it down with a test prevents accidentally re-introducing it.
  • Detection-idiom checks: span<int> rejects il construction; span<const float> rejects initializer_list<int> (no implicit conversions, even safe ones).

Local: 52/52 passing.

Fixes #2

P2447R6 originally added an il constructor for C++26 but it caused silent behavior changes for span<const bool>{ptr, size} (the (bool*, size_t)
arguments would convert to two bools and grab the il ctor). P4144R1 reverted it for that reason. P4190R0 brings it back with the right constraints to avoid the regression:

- is_const_v<element_type>: the il's underlying array is a temporary, so
  only span<const T> can sensibly observe it
- same_as<value_type, InitListValueType>: exact match, no conversions -
  this is what stops the (ptr, size) -> bool gotcha from happening

The implementation uses a dummy class T_ = ElementType template parameter. So is_const_v stays dependent on a function template parameter. Without
it the check would be non-dependent and hard-error inside span<int> rather than just SFINAE-out.

Added six new tests cover dynamic and fixed extent construction (using the function-call idiom since the il's underlying array is a full-expression
temporary), const bool from braced-init-list, named initializer_list with extended array lifetime, pointer+size on span<const bool> still resolving
to the It+count ctor (the regression P4144R1 reverted), and detection-idiom checks confirming span<int> rejects il construction and the same_as constraint blocks implicit conversions like int -> float.
ssam18 added 2 commits May 1, 2026 08:14
Pure formatter output. Aligns the initializer_list ctor template
declarations and the at() test cases under .clang-format's
AlignConsecutiveDeclarations rule. No logic changes.
@coveralls
Copy link
Copy Markdown

Coverage Status

coverage: 100.0%. remained the same — initializer-list-ctor-p4190 into main

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

implement c++29 span over initializer list

3 participants