458 lines
15 KiB
Markdown
458 lines
15 KiB
Markdown
[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);
|