Title
move_only_function assignment operators seem to be defined suboptimal
Status
new
Section
[func.wrap.move.ctor]
Submitter
Alexander Guteniev

Created on 2021-11-20.00:00:00 last changed 6 days ago

Messages

Date: 2021-11-20.17:49:05

Proposed resolution:

This wording is relative to N4901.

  1. Modify [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);

Date: 2021-11-20.00:00:00

[func.wrap.move.ctor]/22 and [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.

History
Date User Action Args
2021-11-20 17:49:05adminsetmessages: + msg12230
2021-11-20 00:00:00admincreate