[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 {template<class R, class... ArgTypes>class function<R(ArgTypes...)> {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<class F> function(F&&);

 function& operator=(const function&);
 function& operator=(function&&);
 function& operator=(nullptr_t) noexcept; template<class F> function& operator=(F&&); template<class F> function& operator=(reference_wrapper<F>) 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<class T> T* target() noexcept; template<class T> const T* target() const noexcept; }; template<class R, class... ArgTypes> function(R(*)(ArgTypes...)) -> function<R(ArgTypes...)>; template<class F> 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<class F> function(F&& f);
`

[8](#con-8)

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

Let FD be decay_t<F>[.](#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<remove_cvref_t<F>, function> is false, and

- [(9.2)](#con-9.2)

is_invocable_r_v<R, FD&, ArgTypes...> 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<FD> is true, and

- [(10.2)](#con-10.2)

is_constructible_v<FD, F> 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<F> 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>(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<class F> function(F) -> function<see below>;
`

[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<R(A...)>[.](#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<int(double)>} â *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<class F> function& operator=(F&& f);
`

[26](#con-26)

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

*Constraints*: is_invocable_r_v<R, decay_t<F>&, 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>(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<class F> function& operator=(reference_wrapper<F> 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*<R>(f, std​::​forward<ArgTypes>(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<class T>       T* target() noexcept;
template<class T> 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<class R, class... ArgTypes>
  bool operator==(const function<R(ArgTypes...)>& 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<class R, class... ArgTypes>
  void swap(function<R(ArgTypes...)>& f1, function<R(ArgTypes...)>& f2) noexcept;
`

[1](#alg-1)

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

*Effects*: As if by: f1.swap(f2);
