[futures.task] # 32 Concurrency support library [[thread]](./#thread) ## 32.10 Futures [[futures]](futures#task) ### 32.10.10 Class template packaged_task [futures.task] #### [32.10.10.1](#general) General [[futures.task.general]](futures.task.general) [1](#general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12544) The class template packaged_task defines a type for wrapping a function or callable object so that the return value of the function or callable object is stored in a future when it is invoked[.](#general-1.sentence-1) [2](#general-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12549) When the packaged_task object is invoked, its stored task is invoked and the result (whether normal or exceptional) stored in the shared state[.](#general-2.sentence-1) Any futures that share the shared state will then be able to access the stored result[.](#general-2.sentence-2) [🔗](#lib:packaged_task) namespace std {template class packaged_task; // *not defined*templateclass packaged_task {public:// construction and destruction packaged_task() noexcept; templateexplicit packaged_task(F&& f); templateexplicit packaged_task(allocator_arg_t, const Allocator& a, F&& f); ~packaged_task(); // no copy packaged_task(const packaged_task&) = delete; packaged_task& operator=(const packaged_task&) = delete; // move support packaged_task(packaged_task&& rhs) noexcept; packaged_task& operator=(packaged_task&& rhs) noexcept; void swap(packaged_task& other) noexcept; bool valid() const noexcept; // result retrieval future get_future(); // executionvoid operator()(ArgTypes... ); void make_ready_at_thread_exit(ArgTypes...); void reset(); }; template packaged_task(R (*)(ArgTypes...)) -> packaged_task; template packaged_task(F) -> packaged_task<*see below*>;} #### [32.10.10.2](#members) Member functions [[futures.task.members]](futures.task.members) [🔗](#lib:packaged_task,constructor) `packaged_task() noexcept; ` [1](#members-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12606) *Effects*: The object has no shared state and no stored task[.](#members-1.sentence-1) [🔗](#lib:packaged_task,constructor_) `template explicit packaged_task(F&& f); ` [2](#members-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12618) *Effects*: Equivalent topackaged_task(allocator_arg, allocator(), std​::​forward(f))[.](#members-2.sentence-1) [🔗](#lib:packaged_task,constructor__) `template explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f); ` [3](#members-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12631) *Constraints*: remove_cvref_t is not the same type as packaged_task[.](#members-3.sentence-1) [4](#members-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12636) *Mandates*: is_invocable_r_v&, ArgTypes...> is true[.](#members-4.sentence-1) [5](#members-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12640) *Preconditions*: Allocator meets the *Cpp17Allocator* requirements ([[allocator.requirements.general]](allocator.requirements.general "16.4.4.6.1 General"))[.](#members-5.sentence-1) [6](#members-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12644) *Effects*: Let A2 beallocator_traits​::​rebind_alloc<*unspecified*> and let a2 be an object of type A2 initialized withA2(a)[.](#members-6.sentence-1) Constructs a new packaged_task object with a stored task of type decay_t and a shared state[.](#members-6.sentence-2) Initializes the object's stored task with std​::​forward(f)[.](#members-6.sentence-3) Uses a2 to allocate storage for the shared state and stores a copy of a2 in the shared state[.](#members-6.sentence-4) [7](#members-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12656) *Throws*: Any exceptions thrown by the initialization of the stored task[.](#members-7.sentence-1) If storage for the shared state cannot be allocated, any exception thrown byA2​::​allocate[.](#members-7.sentence-2) [🔗](#lib:packaged_task,constructor___) `template packaged_task(F) -> packaged_task; ` [8](#members-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12669) *Constraints*: &F​::​operator() is well-formed when treated as an unevaluated operand ([[expr.context]](expr.context#term.unevaluated.operand "7.2.3 Context dependence")) and either - [(8.1)](#members-8.1) F​::​operator() is a non-static member function anddecltype(​&F​::​operator()) is either of the formR(G​::​*)(A...) cv &opt noexceptopt or of the formR(*)(G, A...) noexceptopt for a type G, or - [(8.2)](#members-8.2) F​::​operator() is a static member function anddecltype(&F​::​operator()) is of the formR(*)(A...) noexceptopt[.](#members-8.sentence-1) [9](#members-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12687) *Remarks*: The deduced type is packaged_task[.](#members-9.sentence-1) [🔗](#lib:packaged_task,constructor____) `packaged_task(packaged_task&& rhs) noexcept; ` [10](#members-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12698) *Effects*: Transfers ownership ofrhs's shared state to *this, leaving rhs with no shared state[.](#members-10.sentence-1) Moves the stored task from rhs to *this[.](#members-10.sentence-2) [11](#members-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12704) *Postconditions*: rhs has no shared state[.](#members-11.sentence-1) [🔗](#lib:operator=,packaged_task) `packaged_task& operator=(packaged_task&& rhs) noexcept; ` [12](#members-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12715) *Effects*: - [(12.1)](#members-12.1) Releases any shared state ([[futures.state]](futures.state "32.10.5 Shared state")); - [(12.2)](#members-12.2) calls packaged_task(std​::​move(rhs)).swap(*this)[.](#members-12.sentence-1) [🔗](#lib:packaged_task,destructor) `~packaged_task(); ` [13](#members-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12731) *Effects*: Abandons any shared state ([[futures.state]](futures.state "32.10.5 Shared state"))[.](#members-13.sentence-1) [🔗](#lib:swap,packaged_task) `void swap(packaged_task& other) noexcept; ` [14](#members-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12742) *Effects*: Exchanges the shared states and stored tasks of *this and other[.](#members-14.sentence-1) [15](#members-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12746) *Postconditions*: *this has the same shared state and stored task (if any) as other prior to the call to swap[.](#members-15.sentence-1) other has the same shared state and stored task (if any) as *this prior to the call to swap[.](#members-15.sentence-2) [🔗](#lib:valid,packaged_task) `bool valid() const noexcept; ` [16](#members-16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12761) *Returns*: true only if *this has a shared state[.](#members-16.sentence-1) [🔗](#lib:get_future,packaged_task) `future get_future(); ` [17](#members-17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12772) *Synchronization*: Calls to this function do not introduce data races ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races")) with calls tooperator() ormake_ready_at_thread_exit[.](#members-17.sentence-1) [*Note [1](#members-note-1)*: Such calls need not synchronize with each other[.](#members-17.sentence-2) — *end note*] [18](#members-18) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12782) *Returns*: A future object that shares the same shared state as *this[.](#members-18.sentence-1) [19](#members-19) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12786) *Throws*: A future_error object if an error occurs[.](#members-19.sentence-1) [20](#members-20) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12790) *Error conditions*: - [(20.1)](#members-20.1) future_already_retrieved if get_future has already been called on a packaged_task object with the same shared state as *this[.](#members-20.1.sentence-1) - [(20.2)](#members-20.2) no_state if *this has no shared state[.](#members-20.2.sentence-1) [🔗](#lib:operator(),packaged_task) `void operator()(ArgTypes... args); ` [21](#members-21) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12805) *Effects*: As if by *INVOKE*(f, t1, t2, …, tN) ([[func.require]](func.require "22.10.4 Requirements")), where f is the stored task of *this andt1, t2, …, tN are the values in args...[.](#members-21.sentence-1) If the task returns normally, the return value is stored as the asynchronous result in the shared state of*this, otherwise the exception thrown by the task is stored[.](#members-21.sentence-2) The shared state of *this is made ready, and any threads blocked in a function waiting for the shared state of *this to become ready are unblocked[.](#members-21.sentence-3) [22](#members-22) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12817) *Throws*: A future_error exception object if there is no shared state or the stored task has already been invoked[.](#members-22.sentence-1) [23](#members-23) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12822) *Error conditions*: - [(23.1)](#members-23.1) promise_already_satisfied if the stored task has already been invoked[.](#members-23.1.sentence-1) - [(23.2)](#members-23.2) no_state if *this has no shared state[.](#members-23.2.sentence-1) [🔗](#lib:make_ready_at_thread_exit,packaged_task) `void make_ready_at_thread_exit(ArgTypes... args); ` [24](#members-24) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12837) *Effects*: As if by *INVOKE*(f, t1, t2, …, tN) ([[func.require]](func.require "22.10.4 Requirements")), where f is the stored task andt1, t2, …, tN are the values in args...[.](#members-24.sentence-1) If the task returns normally, the return value is stored as the asynchronous result in the shared state of*this, otherwise the exception thrown by the task is stored[.](#members-24.sentence-2) In either case, this is done without making that state ready ([[futures.state]](futures.state "32.10.5 Shared state")) immediately[.](#members-24.sentence-3) Schedules the shared state to be made ready when the current thread exits, after all objects with thread storage duration associated with the current thread have been destroyed[.](#members-24.sentence-4) [25](#members-25) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12849) *Throws*: future_error if an error condition occurs[.](#members-25.sentence-1) [26](#members-26) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12853) *Error conditions*: - [(26.1)](#members-26.1) promise_already_satisfied if the stored task has already been invoked[.](#members-26.1.sentence-1) - [(26.2)](#members-26.2) no_state if *this has no shared state[.](#members-26.2.sentence-1) [🔗](#lib:reset,packaged_task) `void reset(); ` [27](#members-27) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12868) *Effects*: Equivalent to:if (!valid()) {throw future_error(future_errc::no_state);}*this = packaged_task(allocator_arg, a, std::move(f)); wheref is the task stored in*this and a is the allocator stored in the shared state[.](#members-27.sentence-1) [*Note [2](#members-note-2)*: This constructs a new shared state for *this[.](#members-27.sentence-2) The old state is abandoned ([[futures.state]](futures.state "32.10.5 Shared state"))[.](#members-27.sentence-3) — *end note*] [28](#members-28) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12885) *Throws*: - [(28.1)](#members-28.1) Any exception thrown by the packaged_task constructor[.](#members-28.1.sentence-1) - [(28.2)](#members-28.2) future_error with an error condition of no_state if *this has no shared state[.](#members-28.2.sentence-1) #### [32.10.10.3](#nonmembers) Globals [[futures.task.nonmembers]](futures.task.nonmembers) [🔗](#lib:swap,packaged_task_) `template void swap(packaged_task& x, packaged_task& y) noexcept; ` [1](#nonmembers-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12903) *Effects*: As if by x.swap(y)[.](#nonmembers-1.sentence-1)