std::function
move constructor does unnecessary workSection: 22.10.17.3.2 [func.wrap.func.con] Status: C++17 Submitter: Geoffrey Romer Opened: 2016-12-15 Last modified: 2020-09-06
Priority: 0
View all other issues in [func.wrap.func.con].
View all issues with C++17 status.
Discussion:
Consider [func.wrap.func.con]/p5:
function(function&& f);Effects: If
!f
,*this
has no target; otherwise, move constructs the target off
into the target of*this
, leavingf
in a valid state with an unspecified value.
By my reading, this wording requires the move constructor of std::function
to construct an entirely new target object.
This is silly: in cases where the target is held in separately allocated memory (i.e. where the target doesn't fit in
std::function
's internal buffer, if any), std::function
's move constructor can be implemented by simply
transferring ownership of the existing target object (which is a simple pointer assignment), so this requirement forces an
unnecessary constructor invocation and probably an unnecessary allocation (the latter can be avoided with something like
double-buffering, but ew). Fixing this would technically be a visible change, but I have a hard time imagining reasonable
code that would be broken by it, especially since both libstdc++ and libc++ already do the sensible thing, constructing a
new target only if the target is held in an internal buffer, and otherwise assigning pointers.
[2017-01-27 Telecon]
Priority 0
Proposed resolution:
This wording is relative to N4618.
Edit 22.10.17.3.2 [func.wrap.func.con]/5 as indicated:
Drafting note: The "equivalent to ... before the construction" wording is based on the wording for
MoveConstructible
.
function(function&& f);-5-
EffectsPostconditions: If!f
,*this
has no target; otherwise,move constructs the target ofthe target off
into the target of*this
, leavingf
*this
is equivalent to the target off
before the construction, andf
is in a valid state with an unspecified value.