This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++17 status.

### 2850. `std::function` move constructor does unnecessary work

Section: 20.14.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 other active issues in [func.wrap.func.con].

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 of `f` into the target of `*this`, leaving `f` 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.

1. Edit 20.14.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- Effects Postconditions: If `!f`, `*this` has no target; otherwise, move constructs the target of `f` into the target of `*this`, leaving `f` the target of `*this` is equivalent to the target of `f` before the construction, and `f` is in a valid state with an unspecified value.