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.

### 3642. `move_only_function` assignment operators seem to be defined suboptimal

Section: 20.14.17.4.3 [func.wrap.move.ctor] Status: New Submitter: Alexander Guteniev Opened: 2021-11-20 Last modified: 2021-11-20

Priority: 3

View other active issues in [func.wrap.move.ctor].

View all other issues in [func.wrap.move.ctor].

View all issues with New status.

Discussion:

20.14.17.4.3 [func.wrap.move.ctor]/22 and 20.14.17.4.3 [func.wrap.move.ctor]/25 define the effects of assignment as following:

>     move_only_function& operator=(move_only_function&& f);

> > Effects: Equivalent to: `move_only_function(std::move(f)).swap(*this);`

> […]

>     template<class F> move_only_function& operator=(F&& f);

> > Effects: Equivalent to: `move_only_function(std::forward<F>(f)).swap(*this);`

The assignment via `swap` with temporary makes the implementation to do the following:

- move out the previous target to a temporary location

- move in the new target

- finally destroy the previous target.

As everything is `noexcept` here, I think it can be short cut to just:

- destroy the previous target.

- move in the new target

Looks like the implementation cannot do such optimization in a generic case with small functor optimization enabled and non-trivial move constructor for the new target and with non-trivial destruction of the previous target, since the difference is observable.

Apparently the optimization is precluded for no reason.

[2022-01-30; Reflector poll]

Set priority to 3 after reflector poll. Some suggestions for NAD, but others disagreed.

Proposed resolution:

This wording is relative to N4901.

1. Modify 20.14.17.4.3 [func.wrap.move.ctor] as indicated:

   >     move_only_function& operator=(move_only_function&& f);

   > > -22- Effects: Sets the target object of `this` to the target object of `f` before the assignment and leaves `f` in a valid state with an unspecified value.Equivalent to: `move_only_function(std::move(f)).swap(*this);`

   > […]

   >     template<class F> move_only_function& operator=(F&& f);

   > > -25- Effects: Equivalent to: `*this = move_only_function(std::forward<F>(f)).swap(*this);`