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.
move_only_function
assignment operators seem to be defined suboptimalSection: 22.10.17.4.3 [func.wrap.move.ctor] Status: New Submitter: Alexander Guteniev Opened: 2021-11-20 Last modified: 2022-01-30
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:
22.10.17.4.3 [func.wrap.move.ctor]/22 and 22.10.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.
Modify 22.10.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 off
before the assignment and leavesf
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);