### 3293. `move_iterator operator+()` has incorrect constraints

**Section:** 25.5.4.9 [move.iter.nonmember] **Status:** WP
**Submitter:** Bo Persson **Opened:** 2019-09-13 **Last modified:** 2021-10-14 09:56:08 UTC

**Priority: **3

**View all other** issues in [move.iter.nonmember].

**View all issues with** WP status.

**Discussion:**

Section 25.5.4.9 [move.iter.nonmember]/2-3 says:

template<class Iterator>
constexpr move_iterator<Iterator>
operator+(iter_difference_t<Iterator> n, const move_iterator<Iterator>& x);

*Constraints:* `x + n` is well-formed and has type `Iterator`.

*Returns:* `x + n`.

However, the return type of this operator is `move_iterator<Iterator>`, so
the expression `x + n` ought to have that type. Also, there is no `operator+`
that matches the constraints, so it effectively disables the addition.

*[2019-10-31 Issue Prioritization]*

Priority to 3 after reflector discussion.

**Previous resolution [SUPERSEDED]:**
This wording is relative to N4830.

Modify 25.5.4.9 [move.iter.nonmember] as indicated:

template<class Iterator>
constexpr move_iterator<Iterator>
operator+(iter_difference_t<Iterator> n, const move_iterator<Iterator>& x);

-2- *Constraints:* `x + n` is well-formed and has type `move_iterator<Iterator>`.

-3- *Returns:* `x + n`.

*[2019-11-04; Casey comments and provides revised wording]*

After applying the P/R the *Constraint* element requires `x + n` to be well-formed (it always is,
since that operation is unconstrained) and requires `x + n` to have type
`move_iterator<Iterator>` (which it always does). Consequently, this *Constraint*
is always satisfied and it has no normative effect. The intent of the change in
P0896R4 was that this operator be constrained to require
addition on the base iterator to be well-formed and have type `Iterator`, which ensures that
the other semantics of this operation are implementable.

*[2021-06-23; Reflector poll]*

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

*[2021-10-14 Approved at October 2021 virtual plenary. Status changed: Voting → WP.]*

**Proposed resolution:**

This wording is relative to N4835.

Modify 25.5.4.9 [move.iter.nonmember] as indicated:

template<class Iterator>
constexpr move_iterator<Iterator>
operator+(iter_difference_t<Iterator> n, const move_iterator<Iterator>& x);

-2- *Constraints:* `x.base() + n` is well-formed and has type `Iterator`.

-3- *Returns:* `x + n`.