[futures.unique.future]

# 32 Concurrency support library [[thread]](./#thread)

## 32.10 Futures [[futures]](futures#unique.future)

### 32.10.7 Class template future [futures.unique.future]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11724)

The class template future defines a type for asynchronous return objects which
do not share their shared state with other asynchronous return objects[.](#1.sentence-1)

A default-constructed future object has no
shared state[.](#1.sentence-2)

A future object with shared state can be created by
functions on [asynchronous providers](futures.state#def:asynchronous_provider "32.10.5 Shared state [futures.state]") or by the move constructor and shares its shared state with
the original asynchronous provider[.](#1.sentence-3)

The result (value or exception) of
a future object
can be
set by
calling a respective function on an
object that shares the same
shared state[.](#1.sentence-4)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11739)

[*Note [1](#note-1)*:

Member functions of future do not synchronize with themselves or with
member functions of shared_future[.](#2.sentence-1)

â *end note*]

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11745)

The effect of calling any member function other than the destructor, the
move assignment operator, share, or valid on a future object for whichvalid() == false is undefined[.](#3.sentence-1)

[*Note [2](#note-2)*:

It is valid to move from a future object for which valid() == false[.](#3.sentence-2)

â *end note*]

*Recommended practice*: Implementations should detect this case and throw an object of typefuture_error with an error condition of future_errc​::​no_state[.](#3.sentence-3)

[ð](#lib:future)

namespace std {template<class R>class future {public: future() noexcept;
 future(future&&) noexcept;
 future(const future&) = delete; ~future();
 future& operator=(const future&) = delete;
 future& operator=(future&&) noexcept;
 shared_future<R> share() noexcept; // retrieving the value*see below* get(); // functions to check statebool valid() const noexcept; void wait() const; template<class Rep, class Period> future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const; template<class Clock, class Duration> future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; };}

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11787)

For the primary template, R shall be an object type that
meets the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#4.sentence-1)

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11791)

The implementation provides the template future and two specializations,future<R&> and future<​void>[.](#5.sentence-1)

These differ only in the return type and return
value of the member function get, as set out in its description, below[.](#5.sentence-2)

[ð](#lib:future,constructor)

`future() noexcept;
`

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11802)

*Effects*: The object does not refer to a shared state[.](#6.sentence-1)

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11806)

*Postconditions*: valid() == false[.](#7.sentence-1)

[ð](#lib:future,constructor_)

`future(future&& rhs) noexcept;
`

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11817)

*Effects*: Move constructs a future object that refers to the shared
state that
was originally referred to by rhs (if any)[.](#8.sentence-1)

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11823)

*Postconditions*: 

- [(9.1)](#9.1)

  valid() returns the same value as rhs.valid() prior to the
constructor invocation[.](#9.1.sentence-1)

- [(9.2)](#9.2)

  rhs.valid() == false[.](#9.2.sentence-1)

[ð](#lib:future,constructor__)

`~future();
`

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11838)

*Effects*: 

- [(10.1)](#10.1)

Releases any shared state ([[futures.state]](futures.state "32.10.5 Shared state"));

- [(10.2)](#10.2)

destroys *this[.](#10.sentence-1)

[ð](#lib:operator=,future)

`future& operator=(future&& rhs) noexcept;
`

[11](#11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11854)

*Effects*: If addressof(rhs) == this is true, there are no effects[.](#11.sentence-1)

Otherwise:

- [(11.1)](#11.1)

  Releases any shared state ([[futures.state]](futures.state "32.10.5 Shared state"))[.](#11.1.sentence-1)

- [(11.2)](#11.2)

  move assigns the contents of rhs to *this[.](#11.2.sentence-1)

[12](#12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11865)

*Postconditions*: 

- [(12.1)](#12.1)

  valid() returns the same value as rhs.valid() prior to the
assignment[.](#12.1.sentence-1)

- [(12.2)](#12.2)

  If addressof(rhs) == this is false,rhs.valid() == false[.](#12.2.sentence-1)

[ð](#lib:share,future)

`shared_future<R> share() noexcept;
`

[13](#13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11884)

*Postconditions*: valid() == false[.](#13.sentence-1)

[14](#14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11888)

*Returns*: shared_future<R>(std​::​move(*this))[.](#14.sentence-1)

[ð](#lib:get,future)

`R future::get();
R& future<R&>::get();
void future<void>::get();
`

[15](#15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11901)

[*Note [3](#note-3)*:

As described above, the template and its two required specializations differ only in
the return type and return value of the member function get[.](#15.sentence-1)

â *end note*]

[16](#16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11907)

*Effects*: 

- [(16.1)](#16.1)

wait()s until the shared state is ready, then retrieves the
value stored in the shared state;

- [(16.2)](#16.2)

releases any shared state ([[futures.state]](futures.state "32.10.5 Shared state"))[.](#16.sentence-1)

[17](#17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11915)

*Postconditions*: valid() == false[.](#17.sentence-1)

[18](#18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11919)

*Returns*: 

- [(18.1)](#18.1)

  future​::​get() returns the value v stored in the object's shared state asstd​::​move(v)[.](#18.1.sentence-1)

- [(18.2)](#18.2)

  future<R&>​::​get() returns the reference stored as value in the object's shared state[.](#18.2.sentence-1)

- [(18.3)](#18.3)

  future<void>​::​get() returns nothing[.](#18.3.sentence-1)

[19](#19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11933)

*Throws*: The stored exception, if an exception was stored in the shared state[.](#19.sentence-1)

[ð](#lib:valid,future)

`bool valid() const noexcept;
`

[20](#20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11944)

*Returns*: true only if *this refers to a shared state[.](#20.sentence-1)

[ð](#lib:wait,future)

`void wait() const;
`

[21](#21)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11955)

*Effects*: Blocks until the shared state is ready[.](#21.sentence-1)

[ð](#lib:wait_for,future)

`template<class Rep, class Period>
  future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
`

[22](#22)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11968)

*Effects*: None if the shared state contains a deferred function ([[futures.async]](futures.async "32.10.9 Function template async")),
otherwise
blocks until the shared state is ready or until
the relative timeout ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications")) specified by rel_time has expired[.](#22.sentence-1)

[23](#23)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11976)

*Returns*: 

- [(23.1)](#23.1)

  future_status​::​deferred if the shared state contains a deferred
function[.](#23.1.sentence-1)

- [(23.2)](#23.2)

  future_status​::​ready if the shared state is ready[.](#23.2.sentence-1)

- [(23.3)](#23.3)

  future_status​::​timeout if the function is returning because the
relative timeout ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications"))
specified by rel_time has expired[.](#23.3.sentence-1)

[24](#24)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11989)

*Throws*: timeout-related exceptions ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications"))[.](#24.sentence-1)

[ð](#lib:wait_until,future)

`template<class Clock, class Duration>
  future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
`

[25](#25)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12001)

*Effects*: None if the shared state contains a deferred function ([[futures.async]](futures.async "32.10.9 Function template async")),
otherwise
blocks until the shared state is ready or until
the absolute timeout ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications")) specified by abs_time has expired[.](#25.sentence-1)

[26](#26)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12009)

*Returns*: 

- [(26.1)](#26.1)

  future_status​::​deferred if the shared state contains a deferred
function[.](#26.1.sentence-1)

- [(26.2)](#26.2)

  future_status​::​ready if the shared state is ready[.](#26.2.sentence-1)

- [(26.3)](#26.3)

  future_status​::​timeout if the function is returning because the
absolute timeout ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications"))
specified by abs_time has expired[.](#26.3.sentence-1)

[27](#27)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12023)

*Throws*: timeout-related exceptions ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications"))[.](#27.sentence-1)
