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.

### 3617. `function`/`packaged_task` deduction guides and deducing `this`

Section: 20.14.17.3.2 [func.wrap.func.con], 32.9.10.2 [futures.task.members] Status: New Submitter: Barry Revzin Opened: 2021-10-09 Last modified: 2021-10-17

Priority: 2

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

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

View all issues with New status.

Discussion:

With the adoption of deducing `this` (P0847), we can now create types whose call operator is an explicit object member function, which means that `decltype(&F::operator())` could have pointer-to-function type rather than pointer-to-member-function type. This means that the deduction guides for `std::function` (20.14.17.3.2 [func.wrap.func.con]) and `std::packaged_task` (32.9.10.2 [futures.task.members]) will simply fail:

>     struct F {
>       int operator()(this const F&) { return 42; }
>     };

>     std::function g = F{}; // error: decltype(&F::operator()) is not of the form R(G::*)(A...) cv &opt noexceptopt

We should update the deduction guides to keep them in line with the core language.

[2021-10-14; Reflector poll]

Set priority to 2 after reflector poll.

Previous resolution [SUPERSEDED]:

> This wording is relative to N4892.

> 1. Modify 20.14.17.3.2 [func.wrap.func.con] as indicated:

>    >     template<class F> function(F) -> function<see below>;

>    > > -16- Constraints: `&F::operator()` is well-formed when treated as an unevaluated operand and `decltype(&F::operator())` is either of the form `R(G::*)(A...) cv &opt noexceptopt` or of the form `R(*)(G cv &opt, A...) noexceptopt` for a class type `G`.

>    > > -17- Remarks: The deduced type is `function<R(A...)>`.

> 2. Modify 32.9.10.2 [futures.task.members] as indicated:

>    >     template<class F> packaged_task(F) -> packaged_task<see below>;

>    > > -7- Constraints: `&F::operator()` is well-formed when treated as an unevaluated operand and `decltype(&F::operator())` is either of the form `R(G::*)(A...) cv &opt noexceptopt` or of the form `R(*)(G cv &opt, A...) noexceptopt` for a class type `G`.

>    > > -8- Remarks: The deduced type is `packaged_task<R(A...)>`.

[2021-10-17; Improved wording based on Tim Song's suggestion]

Proposed resolution:

This wording is relative to N4892.

1. Modify 20.14.17.3.2 [func.wrap.func.con] as indicated:

   >     template<class F> function(F) -> function<see below>;

   > > -16- Constraints: `&F::operator()` is well-formed when treated as an unevaluated operand and `decltype(&F::operator())` is either of the form `R(G::*)(A...) cv &opt noexceptopt` or of the form `R(*)(G, A...) noexceptopt` for a class type `G`.

   > > -17- Remarks: The deduced type is `function<R(A...)>`.

2. Modify 32.9.10.2 [futures.task.members] as indicated:

   >     template<class F> packaged_task(F) -> packaged_task<see below>;

   > > -7- Constraints: `&F::operator()` is well-formed when treated as an unevaluated operand and `decltype(&F::operator())` is either of the form `R(G::*)(A...) cv &opt noexceptopt` or of the form `R(*)(G, A...) noexceptopt` for a class type `G`.

   > > -8- Remarks: The deduced type is `packaged_task<R(A...)>`.