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.

### 3618. Unnecessary `iter_move` for `transform_view::iterator`

Section: 26.7.9.3 [range.transform.iterator] Status: WP Submitter: Barry Revzin Opened: 2021-10-12 Last modified: 2022-02-10

Priority: Not Prioritized

View all other issues in [range.transform.iterator].

View all issues with WP status.

Discussion:

`transform_view`'s iterator currently specifies a customization point for `iter_move`. This customization point does the same thing that the default implementation would do — `std::move(*E)` if `*E` is an lvalue, else `*E` — except that it is only there to provide the correct conditional `noexcept` specification. But for `iota_view`, we instead provide a `noexcept`-specifier on the iterator's `operator*`. We should do the same thing for both, and the simplest thing would be:

Change 26.7.9.3 [range.transform.iterator] to put the whole body into `noexcept`:

>     constexpr decltype(auto) operator*() const noexcept(noexcept(invoke(*parent_->fun_, *current_))) {
>       return invoke(*parent_->fun_, *current_);
>     }

And to remove this:

>     friend constexpr decltype(auto) iter_move(const iterator& i)
>       noexcept(noexcept(invoke(*i.parent_->fun_, *i.current_))) {
>       if constexpr (is_lvalue_reference_v<decltype(*i)>)
>         return std::move(*i);
>       else
>         return *i;
>     }

[2022-01-29; Reflector poll]

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

[2022-02-10 Approved at February 2022 virtual plenary. Status changed: Tentatively Ready → WP.]

Proposed resolution:

This wording is relative to N4892.

1. Modify 26.7.9.3 [range.transform.iterator], class template `transform_view::iterator`, as indicated:

   >     […]
   >     constexpr decltype(auto) operator*() const noexcept(noexcept(invoke(*parent_->fun_, *current_))) {
   >       return invoke(*parent_->fun_, *current_);
   >     }
   >     […]
   >     friend constexpr decltype(auto) iter_move(const iterator& i)
   >       noexcept(noexcept(invoke(*i.parent_->fun_, *i.current_))) {
   >       if constexpr (is_lvalue_reference_v<decltype(*i)>)
   >         return std::move(*i);
   >       else
   >         return *i;
   >     }
   >     […]