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

1288. std::function assignment from rvalues

Section: 22.10.17.3.2 [func.wrap.func.con] Status: C++11 Submitter: Jonathan Wakely Opened: 2009-12-13 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [func.wrap.func.con].

View all issues with C++11 status.

Discussion:

In 22.10.17.3.2 [func.wrap.func.con]

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

20 Effects: function(f).swap(*this);

21 Returns: *this

This assignment operator can be called such that F is an rvalue-reference e.g.

func.operator=<F&&>(f);

There are two issues with this.

  1. the effects mean that f is passed as an lvalue and so there will be an unnecessary copy. The argument should be forwarded, so that the copy can be avoided.
  2. It should not be necessary to use that syntax to pass an rvalue. As F is a deduced context it can be made to work with either lvalues or rvalues.

The same issues apply to function::assign.

N.B. this issue is not related to 1287 and applies whether that issue is resolved or not. The wording below assumes the resolution of LWG 1258 has been applied.

[ 2009-12-16 Moved to Tentatively Ready after 5 positive votes on c++std-lib. ]

[ 201002-11 Opened by Alisdair for the purpose of merging 1258 into this issue as there is a minor conflict. ]

[ 2010-02-11 Moved to Tentatively Ready after 5 positive votes on c++std-lib. ]

Proposed resolution:

In 22.10.17.3.2 [func.wrap.func.con]

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

20 Effects: function(std::forward<F>(f)).swap(*this);

21 Returns: *this

In 22.10.17.3.3 [func.wrap.func.mod]

template<class F, Allocator Allocclass A>
  void assign(F&& f, const Alloc& a);

3 Effects: function(f, aallocator_arg, a, std::forward<F>(f)).swap(*this);

Update member function signature for class template in 22.10.17.3 [func.wrap.func]

template<class F> function& operator=(F&&);

template<class F, class A> void assign(F&&, const A&);