Document Number:





Programming Language C++

Peter Sommerlad <>

N3269: shared_future(future<R>&& rhs) should be allowed to throw


Requiring the constructor shared_future(future<R>&& rhs) not to throw is a pessimisation of the case where a future is returned from a call to async(function,launch::deferred) and possible other cases.

Such a future not dealing with multiple threads only needs to keep (a copy of) the function to be called it later. However, creating a shared_future from that future will require more infrastructure, like space for the value of type R, an exception_ptr, and a synchronized reference counter for the shared_future's instances.

Enforcing the constructor shared_future(future<R>&& rhs) not to throw, implies that any implementation of future will need to pre-allocate space for shared_future's infrastructure, that also requires an operating system resource for synchronization, regardless if is ever needed.

All this came up when discussing D/N3267 and Concurrency Working Group decided that the constructor shared_future(future<R>&& rhs) should be allowed to throw.

Proposed Changes

  1. In 30.6.7 [futures.shared_future] after p.3 shared_future synopsis remove noexcept:

    shared_future(future<R>&& rhs) noexcept;
  2. In 30.6.7 [futures.shared_future] after p.8 remove noexcept and insert the following paragraphs describing this constructor before shared_future(shared_future<R>&& rhs) noexcept;:

    shared_future(future<R>&& rhs) noexcept;

    ? Effects:

    • constructs a shared_future object that refers to the shared state that was originally referred to by rhs (if any).
    • If the constructor exits with an exception, rhs shall remain unchanged.

    ? Postconditions:

    • valid() returns the same value as rhs.valid() returned prior to the constructor invocation.
    • rhs.valid() == false.