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

### 3546. `common_iterator`'s `postfix-proxy` is not quite right

Section: 23.5.4.5 [common.iter.nav] Status: WP Submitter: Tim Song Opened: 2021-04-23 Last modified: 2021-06-07

Priority: Not Prioritized

View all other issues in [common.iter.nav].

View all issues with WP status.

Discussion:

P2259R1 modeled `common_iterator::operator++(int)`'s `postfix-proxy` class on the existing proxy class used by `common_iterator::operator->`, but in doing so it overlooked two differences:

- `operator->`'s proxy is only used when `iter_reference_t<I>` is not a reference type; this is not the case for `postfix-proxy`;

- `operator->` returns a prvalue proxy, while `operator++`'s `postfix-proxy` is returned by (elidable) move, so the latter needs to require `iter_value_t<I>` to be `move_constructible`.

The proposed wording has been implemented and tested.

[2021-05-10; Reflector poll]

Set status to Tentatively Ready after five votes in favour during reflector poll.

[2021-05-17; Reflector poll]

Set status to Tentatively Ready after five votes in favour during reflector poll.

[2021-06-07 Approved at June 2021 virtual plenary. Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N4885.

1. Modify 23.5.4.5 [common.iter.nav] as indicated:

   >     decltype(auto) operator++(int);

   > > -4- Preconditions: `holds_alternative<I>(v_)` is `true`.

   > > -5- Effects: If `I` models `forward_iterator`, equivalent to:

   > > >     common_iterator tmp = *this;
   > > >     ++*this;
   > > >     return tmp;

   > > Otherwise, if `requires (I& i) { { *i++ } -> can-reference; }` is `true` or `constructible_from<iter_value_t<I>, iter_reference_t<I>> && move_constructible<iter_value_t<I>>` is `false`, equivalent to:

   > > >     return get<I>(v_)++;

   > > Otherwise, equivalent to:

   > > >     postfix-proxy p(**this);
   > > >     ++*this;
   > > >     return p;

   > > where `postfix-proxy` is the exposition-only class:

   > > >     class postfix-proxy {
   > > >       iter_value_t<I> keep_;
   > > >       postfix-proxy(iter_reference_t<I>&& x)
   > > >         : keep_(std::moveforward<iter_reference_t<I>>(x)) {}
   > > >     public:
   > > >       const iter_value_t<I>& operator*() const {
   > > >         return keep_;
   > > >       }
   > > >     };