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.

### 1070. Ambiguous move overloads in function

Section: 22.10.17.3 [func.wrap.func] Status: C++11 Submitter: Howard Hinnant Opened: 2009-03-19 Last modified: 2016-01-28

Priority: Not Prioritized

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

View all issues with C++11 status.

Discussion:

The synopsis in 22.10.17.3 [func.wrap.func] says:

>     template<Returnable R, CopyConstructible... ArgTypes>
>     class function<R(ArgTypes...)>
>     {
>         ...
>         template<class F>
>           requires CopyConstructible<F> && Callable<F, ArgTypes...>
>                 && Convertible<Callable<F, ArgTypes...>::result_type, R>
>           function(F);
>         template<class F>
>           requires CopyConstructible<F> && Callable<F, ArgTypes...>
>                 && Convertible<Callable<F, ArgTypes...>::result_type, R>
>           function(F&&);
>         ...
>         template<class F, Allocator Alloc> function(allocator_arg_t, const Alloc&, F);
>         template<class F, Allocator Alloc> function(allocator_arg_t, const Alloc&, F&&);
>         ...
>         template<class F>
>           requires CopyConstructible<F> && Callable<F, ArgTypes..>
>                 && Convertible<Callable<F, ArgTypes...>::result_type
>           function& operator=(F);
>         template<class F>
>           requires CopyConstructible<F> && Callable<F, ArgTypes...>
>                 && Convertible<Callable<F, ArgTypes...>::result_type, R>
>           function& operator=(F&&);
>         ...
>     };

Each of the 3 pairs above are ambiguous. We need only one of each pair, and we could do it with either one. If we choose the `F&&` version we need to bring `decay` into the definition to get the pass-by-value behavior. In the proposed wording I've gotten lazy and just used the pass-by-value signature.

[ 2009-05-01 Daniel adds: ]

> 1024 modifies the second removed constructor.

[ Batavia (2009-05): ]

> We briefly discussed whether we ought support moveable function objects, but decided that should be a separate issue if someone cares to propose it.

> Move to Tentatively Ready.

Proposed resolution:

Change the synopsis of 22.10.17.3 [func.wrap.func], and remove the associated definitions in 22.10.17.3.2 [func.wrap.func.con]:

>     template<Returnable R, CopyConstructible... ArgTypes>
>     class function<R(ArgTypes...)>
>     {
>         ...
>         template<class F>
>           requires CopyConstructible<F> && Callable<F, ArgTypes...>
>                 && Convertible<Callable<F, ArgTypes...>::result_type, R>
>           function(F);
>         template<class F>
>           requires CopyConstructible<F> && Callable<F, ArgTypes...>
>                 && Convertible<Callable<F, ArgTypes...>::result_type, R>
>           function(F&&);
>         ...
>         template<class F, Allocator Alloc> function(allocator_arg_t, const Alloc&, F);
>         template<class F, Allocator Alloc> function(allocator_arg_t, const Alloc&, F&&);
>         ...
>         template<class F>
>           requires CopyConstructible<F> && Callable<F, ArgTypes..>
>                 && Convertible<Callable<F, ArgTypes...>::result_type
>           function& operator=(F);
>         template<class F>
>           requires CopyConstructible<F> && Callable<F, ArgTypes...>
>                 && Convertible<Callable<F, ArgTypes...>::result_type, R>
>           function& operator=(F&&);
>         ...
>     };