[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 {templateclass future {public: future() noexcept; future(future&&) noexcept; future(const future&) = delete; ~future(); future& operator=(const future&) = delete; future& operator=(future&&) noexcept; shared_future share() noexcept; // retrieving the value*see below* get(); // functions to check statebool valid() const noexcept; void wait() const; template future_status wait_for(const chrono::duration& rel_time) const; template future_status wait_until(const chrono::time_point& 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 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 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(std​::​move(*this))[.](#14.sentence-1) [🔗](#lib:get,future) `R future::get(); R& future::get(); void future::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​::​get() returns the reference stored as value in the object's shared state[.](#18.2.sentence-1) - [(18.3)](#18.3) future​::​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 future_status wait_for(const chrono::duration& 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 future_status wait_until(const chrono::time_point& 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)