This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

### 3287. Exposition-only `cpp17-input-iterator` concept is needlessly complex

Section: 23.3.2.3 [iterator.traits] Status: New Submitter: Eric Niebler Opened: 2019-09-10 Last modified: 2020-09-06

Priority: 3

View all other issues in [iterator.traits].

View all issues with New status.

Discussion:

The new C++20 iterator concepts use `common_reference` to constrain the value, reference, and rvalue_reference associated types in order to support proxy references (see 23.3.4.2 [iterator.concept.readable]).

However, the C++17 iterators did not support proxy references, so the use of `common_reference` in 23.3.2.3 [iterator.traits]/p2 is needlessly complex. The `common_reference` constraints can be replaced with simple convertibility requirements to a `const` lvalue reference to the value type.

This fix has been implemented in range-v3.

[2019-10-14 Issue Prioritization]

Priority to 3 after reflector discussion.

Proposed resolution:

This wording is relative to N4830.

1. Modify 23.3.2.3 [iterator.traits] as indicated:

   > -2- The definitions in this subclause make use of the following exposition-only concepts:

   > >     template<class I>
   > >     concept cpp17-iterator =
   > >       copyable<I> && requires(I i) {
   > >         {   *i } -> can-reference;
   > >         {  ++i } -> same_as<I&>;
   > >         { *i++ } -> can-reference;
   > >       };

   > >     template<class I>
   > >     concept cpp17-input-iterator =
   > >       cpp17-iterator<I> && equality_comparable<I> && requires(I i) {
   > >         typename incrementable_traits<I>::difference_type;
   > >         typename readable_traits<I>::value_type;
   > >         typename common_reference_t<iter_reference_t<I>&&,
   > >                                     typename readable_traits<I>::value_type&>;
   > >         typename common_reference_t<decltype(*i++)&&,
   > >                                     typename readable_traits<I>::value_type&>;
   > >         { *i } -> convertible_to<const typename readable_traits<I>::value_type&>;
   > >         { *i++ } -> convertible_to<const typename readable_traits<I>::value_type&>;
   > >         requires signed_integral<typename incrementable_traits<I>::difference_type>;
   > >       };

   > >     […]