transform_view::iterator<true>::value_type
and iterator_category
should
use const F&
Section: 25.7.9.3 [range.transform.iterator] Status: C++23 Submitter: Tim Song Opened: 2021-06-06 Last modified: 2023-11-22
Priority: 2
View all other issues in [range.transform.iterator].
View all issues with C++23 status.
Discussion:
Iterators obtained from a const transform_view
invoke the
transformation function as const
, but the value_type
and
iterator_category
determination uses plain F&
, i.e., non-const
.
[2021-06-14; Reflector poll]
Set priority to 2 after reflector poll, send to SG9 for design clarification.
Should r
and as_const(r)
guarantee same elements?
[2022-07-08; Reflector poll]
SG9 has decided to proceed with this PR in its 2021-09-13 telecon and not block the issue for a paper on the more general const/non-const problem.
Set status to Tentatively Ready after five votes in favour during reflector poll.
[2022-07-15; LWG telecon: move to Ready]
[2022-07-25 Approved at July 2022 virtual plenary. Status changed: Ready → WP.]
Proposed resolution:
This wording is relative to N4885.
Modify 25.7.9.3 [range.transform.iterator] as indicated:
namespace std::ranges { template<input_range V, copy_constructible F> requires view<V> && is_object_v<F> && regular_invocable<F&, range_reference_t<V>> && can-reference<invoke_result_t<F&, range_reference_t<V>>> template<bool Const> class transform_view<V, F>::iterator { private: […] public: using iterator_concept = see below; using iterator_category = see below; // not always present using value_type = remove_cvref_t<invoke_result_t<maybe-const<Const, F>&, range_reference_t<Base>>>; using difference_type = range_difference_t<Base>; […] }; }-1- […]
-2- The member typedef-nameiterator_category
is defined if and only ifBase
modelsforward_range
. In that case,iterator::iterator_category
is defined as follows: LetC
denote the typeiterator_traits<iterator_t<Base>>::iterator_category
.
(2.1) — If
is_lvalue_reference_v<invoke_result_t<maybe-const<Const, F>&, range_reference_t<Base>>>
istrue
, then
(2.1.1) — […]
(2.1.2) — […]
(2.2) — Otherwise,
iterator_category
denotesinput_iterator_tag
.