counted_iterator/move_iterator::base() const &
Section: 24.5.4 [move.iterators], 24.5.7 [iterators.counted] Status: C++23 Submitter: Patrick Palka Opened: 2020-02-07 Last modified: 2023-11-22
Priority: 2
View all other issues in [move.iterators].
View all issues with C++23 status.
Discussion:
It is not possible to use the const &
overloads of counted_iterator::base()
or
move_iterator::base()
to get at an underlying move-only iterator in order to compare it
against a sentinel.
auto v = r | views::take(5); ranges::begin(v) == ranges::end(v);
is invalid when r
is a view
whose begin()
is a move-only input iterator.
The code is invalid because ranges::take_view::sentinel::operator==()
must call
counted_iterator::base()
to compare the underlying iterator against its sentinel, and
therefore this operator==()
requires that the underlying iterator is copy_constructible
.
const & base()
overloads return the underlying iterator by const
reference.
Remove the copy_constructible
constraint on these overloads. Perhaps the base()
overloads for the iterator wrappers in 25.7 [range.adaptors] could use the same treatment?
[2020-02 Prioritized as P2 Monday morning in Prague]
[2021-01-28; Reflector poll]
Set status to Tentatively Ready after five votes in favour during reflector poll.
[2021-02-26 Approved at February 2021 virtual plenary. Status changed: Tentatively Ready → WP.]
Proposed resolution:
This wording is relative to N4849.
Modify 24.5.4.2 [move.iterator], class template move_iterator
synopsis, as indicated:
namespace std { template<class Iterator> class move_iterator { public: using iterator_type = Iterator; […] constexpr const iterator_type& base() const &; constexpr iterator_type base() &&; […] }; }
Modify 24.5.4.5 [move.iter.op.conv] as indicated:
constexpr const Iterator& base() const &;
-1- Constraints:Iterator
satisfiescopy_constructible
.-2- Preconditions:-3- Returns:Iterator
modelscopy_constructible
.current
.
Modify 24.5.7.1 [counted.iterator], class template counted_iterator
synopsis, as indicated:
namespace std { template<input_or_output_iterator I> class counted_iterator { public: using iterator_type = I; […] constexpr const I& base() const &requires copy_constructible<I>; constexpr I base() &&; […] }; }
Modify 24.5.7.3 [counted.iter.access] as indicated:
constexpr const I& base() const &requires copy_constructible<I>;-1- Effects: Equivalent to:
return current;