Files
2025-10-25 03:02:53 +03:00

458 lines
15 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.2Constructors 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.3Modifiers"), function modifiersvoid swap(function&) noexcept; // [[func.wrap.func.cap]](#cap "22.10.17.3.4Capacity"), function capacityexplicit operator bool() const noexcept; // [[func.wrap.func.inv]](#inv "22.10.17.3.5Invocation"), function invocation R operator()(ArgTypes...) const; // [[func.wrap.func.targ]](#targ "22.10.17.3.6Target 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.3Definitions")), given a call
signature ([[func.def]](func.def "22.10.3Definitions"))[.](#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.3Definitions")) whose call signature ([[func.def]](func.def "22.10.3Definitions"))
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.2Template 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.4Requirements")),
where f is the target object ([[func.def]](func.def "22.10.3Definitions")) 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);