input_iterator
but not equality_comparable
look like
C++17 output iteratorsSection: 24.3.2.3 [iterator.traits] Status: Resolved Submitter: Eric Niebler Opened: 2019-09-10 Last modified: 2021-05-18
Priority: 2
View all other issues in [iterator.traits].
View all issues with Resolved status.
Discussion:
In C++20, if an iterator doesn't define all of the associated iterator types (value,
category, reference, and difference), the primary std::iterator_traits
template picks
a category based on structural conformance to a set of implementation-defined concepts that
capture the old iterator requirements tables. (See 24.3.2.3 [iterator.traits].) In C++17,
input iterators were required to be equality-comparable with themselves. In C++20 that is not
the case, so such iterators must not be given intput_iterator_tag
as a category.
They don't, so that's all well and good.
std::output_iterator_tag
. It does this even if there is a nested
iterator_category
typedef declaring the iterator to be input. (This will happen
frequently as C++20 iterators don't require iterators to declare their reference type, for
instance.) This will be extremely confusing to users who, understandably, will be at a loss to
understand why the legacy STL algorithms think their iterator is an output iterator when they
have clearly stated that the iterator is input!
The fix is to tweak the specification such that the output category is assigned to an iterator
only (a) if it declares its category to be output, or (b) it doesn't specify a category at all.
The result, for the user, is that their iterator simply won't look like a C++17 iterator at all,
because it isn't!
Suggested priority: P1. We can't make this change after C++20 because it would be an observable change.
This fix has been implemented in range-v3.
[2019-10-12 Priority set to 1 after reflector discussion]
[2019-11 Wednesday night Issue processing in Belfast]
Much discussion along with 3289. CC to write rationale for NAD.
[2020-02-13, Prague; Priority reduced to 2 after LWG discussion]
[2021-05-18 Resolved by the adoption of P2259R1 at the February 2021 plenary. Status changed: New → Resolved.]
Proposed resolution:
This wording is relative to N4830.
Modify 24.3.2.3 [iterator.traits] as indicated:
-3- The members of a specialization
iterator_traits<I>
generated from theiterator_traits
primary template are computed as follows:
(3.1) — If
I
has valid […][…]
(3.3) — Otherwise, if
I
satisfies the exposition-only conceptcpp17-iterator
and either
I::iterator_category
is valid and denotesoutput_iterator_tag
or a type publicly and unambiguously derived fromoutput_iterator_tag
, orthere is no type
I::iterator_category
then
iterator_traits<I>
has the following publicly accessible members:[…]