[func.wrap.func] # 22 General utilities library [[utilities]](./#utilities) ## 22.10 Function objects [[function.objects]](function.objects#func.wrap.func) ### 22.10.17 Polymorphic function wrappers [[func.wrap]](func.wrap#func) #### 22.10.17.3 Class template function [func.wrap.func] #### [22.10.17.3.1](#general) General [[func.wrap.func.general]](func.wrap.func.general) [🔗](#lib:result_type,function) namespace std {templateclass function {public:using result_type = R; // [[func.wrap.func.con]](#con "22.10.17.3.2 Constructors and destructor"), construct/copy/destroy function() noexcept; function(nullptr_t) noexcept; function(const function&); function(function&&) noexcept; template function(F&&); function& operator=(const function&); function& operator=(function&&); function& operator=(nullptr_t) noexcept; template function& operator=(F&&); template function& operator=(reference_wrapper) noexcept; ~function(); // [[func.wrap.func.mod]](#mod "22.10.17.3.3 Modifiers"), function modifiersvoid swap(function&) noexcept; // [[func.wrap.func.cap]](#cap "22.10.17.3.4 Capacity"), function capacityexplicit operator bool() const noexcept; // [[func.wrap.func.inv]](#inv "22.10.17.3.5 Invocation"), function invocation R operator()(ArgTypes...) const; // [[func.wrap.func.targ]](#targ "22.10.17.3.6 Target access"), function target accessconst type_info& target_type() const noexcept; template T* target() noexcept; template const T* target() const noexcept; }; template function(R(*)(ArgTypes...)) -> function; template function(F) -> function<*see below*>;} [1](#general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13701) The function class template provides polymorphic wrappers that generalize the notion of a function pointer[.](#general-1.sentence-1) Wrappers can store, copy, and call arbitrary callable objects ([[func.def]](func.def "22.10.3 Definitions")), given a call signature ([[func.def]](func.def "22.10.3 Definitions"))[.](#general-1.sentence-2) [2](#general-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13707) The function class template is a call wrapper ([[func.def]](func.def "22.10.3 Definitions")) whose call signature ([[func.def]](func.def "22.10.3 Definitions")) is R(ArgTypes...)[.](#general-2.sentence-1) [3](#general-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13712) [*Note [1](#general-note-1)*: The types deduced by the deduction guides for function might change in future revisions of C++[.](#general-3.sentence-1) — *end note*] #### [22.10.17.3.2](#con) Constructors and destructor [[func.wrap.func.con]](func.wrap.func.con) [🔗](#lib:function,constructor) `function() noexcept; ` [1](#con-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13726) *Postconditions*: !*this[.](#con-1.sentence-1) [🔗](#lib:function,constructor_) `function(nullptr_t) noexcept; ` [2](#con-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13737) *Postconditions*: !*this[.](#con-2.sentence-1) [🔗](#lib:function,constructor__) `function(const function& f); ` [3](#con-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13748) *Postconditions*: !*this if !f; otherwise, the target object of *this is a copy of the target object of f[.](#con-3.sentence-1) [4](#con-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13753) *Throws*: Nothing if f's target is a specialization of reference_wrapper or a function pointer[.](#con-4.sentence-1) Otherwise, may throw bad_alloc or any exception thrown by the copy constructor of the stored callable object[.](#con-4.sentence-2) [5](#con-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13760) *Recommended practice*: Implementations should avoid the use of dynamically allocated memory for small callable objects, for example, wheref's target is an object holding only a pointer or reference to an object and a member function pointer[.](#con-5.sentence-1) [🔗](#lib:function,constructor___) `function(function&& f) noexcept; ` [6](#con-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13774) *Postconditions*: If !f, *this has no target; otherwise, the target of *this is equivalent to the target of f before the construction, andf is in a valid state with an unspecified value[.](#con-6.sentence-1) [7](#con-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13781) *Recommended practice*: Implementations should avoid the use of dynamically allocated memory for small callable objects, for example, where f's target is an object holding only a pointer or reference to an object and a member function pointer[.](#con-7.sentence-1) [🔗](#lib:function,constructor____) `template function(F&& f); ` [8](#con-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13795) Let FD be decay_t[.](#con-8.sentence-1) [9](#con-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13798) *Constraints*: - [(9.1)](#con-9.1) is_same_v, function> is false, and - [(9.2)](#con-9.2) is_invocable_r_v is true[.](#con-9.sentence-1) [10](#con-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13807) *Mandates*: - [(10.1)](#con-10.1) is_copy_constructible_v is true, and - [(10.2)](#con-10.2) is_constructible_v is true[.](#con-10.sentence-1) [11](#con-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13816) *Preconditions*: FD meets the [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#con-11.sentence-1) [12](#con-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13820) *Postconditions*: !*this is true if any of the following hold: - [(12.1)](#con-12.1) f is a null function pointer value[.](#con-12.1.sentence-1) - [(12.2)](#con-12.2) f is a null member pointer value[.](#con-12.2.sentence-1) - [(12.3)](#con-12.3) remove_cvref_t is a specialization of the function class template, and!f is true[.](#con-12.3.sentence-1) [13](#con-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13831) Otherwise, *this has a target object of type FD direct-non-list-initialized with std​::​forward(f)[.](#con-13.sentence-1) [14](#con-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13835) *Throws*: Nothing if FD is a specialization of reference_wrapper or a function pointer type[.](#con-14.sentence-1) Otherwise, may throw bad_alloc or any exception thrown by the initialization of the target object[.](#con-14.sentence-2) [15](#con-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13843) *Recommended practice*: Implementations should avoid the use of dynamically allocated memory for small callable objects, for example, where f refers to an object holding only a pointer or reference to an object and a member function pointer[.](#con-15.sentence-1) [🔗](#con-itemdecl:6) `template function(F) -> function; ` [16](#con-16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13857) *Constraints*: &F​::​operator() is well-formed when treated as an unevaluated operand and either - [(16.1)](#con-16.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 - [(16.2)](#con-16.2) F​::​operator() is a static member function anddecltype(&F​::​operator()) is of the formR(*)(A...) noexceptopt[.](#con-16.sentence-1) [17](#con-17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13874) *Remarks*: The deduced type is function[.](#con-17.sentence-1) [18](#con-18) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13878) [*Example [1](#con-example-1)*: void f() {int i{5}; function g = [&](double) { return i; }; // deduces function} — *end example*] [🔗](#lib:operator=,function) `function& operator=(const function& f); ` [19](#con-19) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13895) *Effects*: As if by function(f).swap(*this); [20](#con-20) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13899) *Returns*: *this[.](#con-20.sentence-1) [🔗](#lib:operator=,function_) `function& operator=(function&& f); ` [21](#con-21) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13910) *Effects*: Replaces the target of *this with the target of f[.](#con-21.sentence-1) [22](#con-22) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13915) *Returns*: *this[.](#con-22.sentence-1) [🔗](#lib:operator=,function__) `function& operator=(nullptr_t) noexcept; ` [23](#con-23) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13926) *Effects*: If *this != nullptr, destroys the target of this[.](#con-23.sentence-1) [24](#con-24) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13930) *Postconditions*: !(*this)[.](#con-24.sentence-1) [25](#con-25) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13934) *Returns*: *this[.](#con-25.sentence-1) [🔗](#lib:operator=,function___) `template function& operator=(F&& f); ` [26](#con-26) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13945) *Constraints*: is_invocable_r_v&, ArgTypes...> is true[.](#con-26.sentence-1) [27](#con-27) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13949) *Effects*: As if by: function(std​::​forward(f)).swap(*this); [28](#con-28) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13953) *Returns*: *this[.](#con-28.sentence-1) [🔗](#lib:operator=,function____) `template function& operator=(reference_wrapper f) noexcept; ` [29](#con-29) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13964) *Effects*: As if by: function(f).swap(*this); [30](#con-30) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13968) *Returns*: *this[.](#con-30.sentence-1) [🔗](#lib:function,destructor) `~function(); ` [31](#con-31) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13979) *Effects*: If *this != nullptr, destroys the target of this[.](#con-31.sentence-1) #### [22.10.17.3.3](#mod) Modifiers [[func.wrap.func.mod]](func.wrap.func.mod) [🔗](#lib:swap,function) `void swap(function& other) noexcept; ` [1](#mod-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13992) *Effects*: Interchanges the target objects of *this and other[.](#mod-1.sentence-1) #### [22.10.17.3.4](#cap) Capacity [[func.wrap.func.cap]](func.wrap.func.cap) [🔗](#lib:operator_bool,function) `explicit operator bool() const noexcept; ` [1](#cap-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14005) *Returns*: true if *this has a target, otherwise false[.](#cap-1.sentence-1) #### [22.10.17.3.5](#inv) Invocation [[func.wrap.func.inv]](func.wrap.func.inv) [🔗](#lib:function,invocation) `R operator()(ArgTypes... args) const; ` [1](#inv-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14019) *Returns*: *INVOKE*(f, std​::​forward(args)...) ([[func.require]](func.require "22.10.4 Requirements")), where f is the target object ([[func.def]](func.def "22.10.3 Definitions")) of *this[.](#inv-1.sentence-1) [2](#inv-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14024) *Throws*: bad_function_call if !*this; otherwise, any exception thrown by the target object[.](#inv-2.sentence-1) #### [22.10.17.3.6](#targ) Target access [[func.wrap.func.targ]](func.wrap.func.targ) [🔗](#lib:target_type,function) `const type_info& target_type() const noexcept; ` [1](#targ-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14038) *Returns*: If *this has a target of type T, typeid(T); otherwise, typeid(void)[.](#targ-1.sentence-1) [🔗](#lib:target,function) `template T* target() noexcept; template const T* target() const noexcept; ` [2](#targ-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14051) *Returns*: If target_type() == typeid(T) a pointer to the stored function target; otherwise a null pointer[.](#targ-2.sentence-1) #### [22.10.17.3.7](#nullptr) Null pointer comparison operator functions [[func.wrap.func.nullptr]](func.wrap.func.nullptr) [🔗](#lib:operator==,function) `template bool operator==(const function& f, nullptr_t) noexcept; ` [1](#nullptr-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14066) *Returns*: !f[.](#nullptr-1.sentence-1) #### [22.10.17.3.8](#alg) Specialized algorithms [[func.wrap.func.alg]](func.wrap.func.alg) [🔗](#lib:swap,function_) `template void swap(function& f1, function& f2) noexcept; ` [1](#alg-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14080) *Effects*: As if by: f1.swap(f2);