Add initializer_list constructor for span<const T> (P4190R0)#9
Open
SamareshSingh wants to merge 3 commits intomainfrom
Open
Add initializer_list constructor for span<const T> (P4190R0)#9SamareshSingh wants to merge 3 commits intomainfrom
SamareshSingh wants to merge 3 commits intomainfrom
Conversation
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.
Pure formatter output. Aligns the initializer_list ctor template declarations and the at() test cases under .clang-format's AlignConsecutiveDeclarations rule. No logic changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the C++29 reinstatement of span's
initializer_listconstructor, the same one P2447R6 added for C++26 and P4144R1 had to revert.The two key constraints (per P4190R0):
is_const_v<element_type>: onlyspan<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:
class T_ = ElementTypetemplate parameter keeps theis_const_vcheck dependent on a function-template parameter. Without it the check would be non-dependent and produce a hard error when instantiatingspan<int>, instead of just SFINAE-ing the il ctor out of overload resolution. Same trick the existing default constructor uses withstd::size_t E = Extent.-Winit-list-lifetimewarning 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:
span<const bool>from{true, false, true}, the case the original C++26 version already handled, has to keep working.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.span<int>rejects il construction;span<const float>rejectsinitializer_list<int>(no implicit conversions, even safe ones).Local: 52/52 passing.
Fixes #2