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.

### 2752. "Throws:" clauses of `async` and `packaged_task` are unimplementable

Section: 33.10.9 [futures.async], 33.10.10.2 [futures.task.members] Status: C++17 Submitter: Billy Robert O'Neal III Opened: 2016-07-07 Last modified: 2017-07-30

Priority: 3

View other active issues in [futures.async].

View all other issues in [futures.async].

View all issues with C++17 status.

Discussion:

`std::async` is a request from the user for type erasure; as any given function gets passed to `async` which returns only `future<ReturnType>`. Therefore, it needs to be able to allocate memory, as other issues (e.g. LWG 2202) indicate. However, async's Throws clause doesn't allow an implementation to do this, as it permits only `future_error`.

`std::packaged_task`'s constructor allocates memory using a user supplied allocator. An implementation needs to call the user's `allocate` to allocate such memory. The user's allocate function is not constrained to throwing only `bad_alloc`; it can raise whatever it wants, but `packaged_task`'s constructor prohibits this.

[2016-07 Chicago]

Alisdair thinks the third bullet is not quite right.

Previous resolution [SUPERSEDED]:

> 1. Change 33.10.9 [futures.async] p6 to:

>    > Throws: `system_error` if `policy == launch::async` and the implementation is unable to start a new thread, or `std::bad_alloc` if memory for the internal data structures could not be allocated.

> 2. Change 33.10.10.2 [futures.task.members] p5 to:

>    >     template <class F>
>    >       packaged_task(F&& f);
>    >     template <class F, class Allocator>
>    >       packaged_task(allocator_arg_t, const Allocator& a, F&& f);

>    > > Throws:

>    > > 1. (?) — A any exceptions thrown by the copy or move constructor of `f`., or
>    > > 2. (?) — For the first version, `std::bad_alloc` if memory for the internal data structures could not be allocated.
>    > > 3. (?) — For the second version, any exceptions thrown by `std::allocator_traits<Allocator>::template rebind<unspecified>::allocate`.

[2016-08 Chicago]

Wed PM: Move to Tentatively Ready

Proposed resolution:

This wording is relative to N4606.

1. Change 33.10.9 [futures.async] p6 to:

   > Throws: `system_error` if `policy == launch::async` and the implementation is unable to start a new thread, or `std::bad_alloc` if memory for the internal data structures could not be allocated.

2. Change 33.10.10.2 [futures.task.members] p5 to:

   >     template <class F>
   >       packaged_task(F&& f);
   >     template <class F, class Allocator>
   >       packaged_task(allocator_arg_t, const Allocator& a, F&& f);

   > > Throws:

   > > 1. (?) — A any exceptions thrown by the copy or move constructor of `f`., or
   > > 2. (?) — For the first version, `std::bad_alloc` if memory for the internal data structures could not be allocated.
   > > 3. (?) — For the second version, any exceptions thrown by `std::allocator_traits<Allocator>::template rebind_traits<unspecified>::allocate`.