elements_view
needs its own sentinel
typeSection: 25.7.23 [range.elements] Status: C++20 Submitter: Tim Song Opened: 2020-02-07 Last modified: 2021-02-25
Priority: 1
View all issues with C++20 status.
Discussion:
elements_view
is effectively a specialized version of transform_view
.
The latter has a custom sentinel
type, and so should elements_view
.
[i, s)
whose value_type
is pair<array<int, 2>, long>
,
where s
is a generic sentinel that checks if the second element (for this range in particular,
the long
) is zero:
struct S { friend bool operator==(input_iterator auto const& i, S) /* additional constraints */ { return get<1>(*i) == 0; } };
If we adapt [i, s)
with views::keys
, then the resulting adapted range would have
surprising behavior when used with S{}
: even though it's nominally a range of
array<int, 2>
, when its iterator is used with the sentinel S{}
it doesn't actually check the second element of the array, but the long
that's not even
part of the value_type
:
void algo(input_range auto&& r) /* constraints */{ // We want to stop at the first element of the range r whose second element is zero. for (auto&& x : subrange{ranges::begin(r), S{}}) { std::cout << get<0>(x); } } using P = pair<array<int, 2>, long>; vector<P> vec = { { {0, 1}, 1L }, { {1, 0}, 1L }, { {2, 2}, 0L } }; subrange r{vec.begin(), S{}}; // range with two elements: {0, 1}, {1, 0} algo(r | views::keys); // checks the long, prints '01' algo(r | views::transform(&P::first)); // checks the second element of the array, prints '0'
This is an API break since it changes the return type of end()
, so it should be
fixed before we ship C++20.
[2020-02 Prioritized as P1 Monday morning in Prague]
[2020-06-11 Voted into the WP in Prague. Status changed: New → WP.]
Proposed resolution:
The proposed wording is contained in P1994R0.