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

1769 lines
63 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]
# 22 General utilities library [[utilities]](./#utilities)
## 22.10 Function objects [[function.objects]](function.objects#func.wrap)
### 22.10.17 Polymorphic function wrappers [func.wrap]
#### [22.10.17.1](#general) General [[func.wrap.general]](func.wrap.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13594)
Subclause [func.wrap] describes polymorphic wrapper classes that
encapsulate arbitrary callable objects[.](#general-1.sentence-1)
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13598)
Let t be an object of a type that is a specialization offunction, copyable_function, or move_only_function,
such that the target object x of t has a type that
is a specialization offunction, copyable_function, or move_only_function[.](#general-2.sentence-1)
Each argument of the
invocation of x evaluated as part of the invocation of t may alias an argument in the same position in the invocation of t that
has the same type, even if the corresponding parameter is not of reference type[.](#general-2.sentence-2)
[*Example [1](#general-example-1)*: move_only_function<void(T)> f{copyable_function<void(T)>{[](T) {}}};
T t;
f(t); // it is unspecified how many copies of T are made — *end example*]
[3](#general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13616)
*Recommended practice*: Implementations should avoid double wrapping when
constructing polymorphic wrappers from one another[.](#general-3.sentence-1)
#### [22.10.17.2](#badcall) Class bad_function_call [[func.wrap.badcall]](func.wrap.badcall)
[1](#badcall-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13624)
An exception of type bad_function_call is thrown byfunction::operator() ([[func.wrap.func.inv]](#func.inv "22.10.17.3.5Invocation"))
when the function wrapper object has no target[.](#badcall-1.sentence-1)
namespace std {class bad_function_call : public exception {public:// see [[exception]](exception "17.9.3Class exception") for the specification of the special member functionsconst char* what() const noexcept override; };}
[🔗](#lib:what,bad_function_call)
`const char* what() const noexcept override;
`
[2](#badcall-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13645)
*Returns*: Animplementation-defined ntbs[.](#badcall-2.sentence-1)
#### [22.10.17.3](#func) Class template function [[func.wrap.func]](func.wrap.func)
#### [22.10.17.3.1](#func.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]](#func.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]](#func.mod "22.10.17.3.3Modifiers"), function modifiersvoid swap(function&) noexcept; // [[func.wrap.func.cap]](#func.cap "22.10.17.3.4Capacity"), function capacityexplicit operator bool() const noexcept; // [[func.wrap.func.inv]](#func.inv "22.10.17.3.5Invocation"), function invocation R operator()(ArgTypes...) const; // [[func.wrap.func.targ]](#func.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](#func.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[.](#func.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"))[.](#func.general-1.sentence-2)
[2](#func.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...)[.](#func.general-2.sentence-1)
[3](#func.general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13712)
[*Note [1](#func.general-note-1)*:
The types deduced by the deduction guides for function might change in future revisions of C++[.](#func.general-3.sentence-1)
— *end note*]
#### [22.10.17.3.2](#func.con) Constructors and destructor [[func.wrap.func.con]](func.wrap.func.con)
[🔗](#lib:function,constructor)
`function() noexcept;
`
[1](#func.con-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13726)
*Postconditions*: !*this[.](#func.con-1.sentence-1)
[🔗](#lib:function,constructor_)
`function(nullptr_t) noexcept;
`
[2](#func.con-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13737)
*Postconditions*: !*this[.](#func.con-2.sentence-1)
[🔗](#lib:function,constructor__)
`function(const function& f);
`
[3](#func.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[.](#func.con-3.sentence-1)
[4](#func.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[.](#func.con-4.sentence-1)
Otherwise, may throw bad_alloc or any exception thrown by the copy constructor of the stored callable object[.](#func.con-4.sentence-2)
[5](#func.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[.](#func.con-5.sentence-1)
[🔗](#lib:function,constructor___)
`function(function&& f) noexcept;
`
[6](#func.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[.](#func.con-6.sentence-1)
[7](#func.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[.](#func.con-7.sentence-1)
[🔗](#lib:function,constructor____)
`template<class F> function(F&& f);
`
[8](#func.con-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13795)
Let FD be decay_t<F>[.](#func.con-8.sentence-1)
[9](#func.con-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13798)
*Constraints*:
- [(9.1)](#func.con-9.1)
is_same_v<remove_cvref_t<F>, function> is false, and
- [(9.2)](#func.con-9.2)
is_invocable_r_v<R, FD&, ArgTypes...> is true[.](#func.con-9.sentence-1)
[10](#func.con-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13807)
*Mandates*:
- [(10.1)](#func.con-10.1)
is_copy_constructible_v<FD> is true, and
- [(10.2)](#func.con-10.2)
is_constructible_v<FD, F> is true[.](#func.con-10.sentence-1)
[11](#func.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[.](#func.con-11.sentence-1)
[12](#func.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)](#func.con-12.1)
f is a null function pointer value[.](#func.con-12.1.sentence-1)
- [(12.2)](#func.con-12.2)
f is a null member pointer value[.](#func.con-12.2.sentence-1)
- [(12.3)](#func.con-12.3)
remove_cvref_t<F> is
a specialization of the function class template, and!f is true[.](#func.con-12.3.sentence-1)
[13](#func.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)[.](#func.con-13.sentence-1)
[14](#func.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[.](#func.con-14.sentence-1)
Otherwise, may throw bad_alloc or
any exception thrown by the initialization of the target object[.](#func.con-14.sentence-2)
[15](#func.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[.](#func.con-15.sentence-1)
[🔗](#func.con-itemdecl:6)
`template<class F> function(F) -> function<see below>;
`
[16](#func.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)](#func.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)](#func.con-16.2)
F::operator() is a static member function anddecltype(&F::operator()) is of the formR(*)(A...) noexceptopt[.](#func.con-16.sentence-1)
[17](#func.con-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13874)
*Remarks*: The deduced type is function<R(A...)>[.](#func.con-17.sentence-1)
[18](#func.con-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13878)
[*Example [1](#func.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](#func.con-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13895)
*Effects*: As if by function(f).swap(*this);
[20](#func.con-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13899)
*Returns*: *this[.](#func.con-20.sentence-1)
[🔗](#lib:operator=,function_)
`function& operator=(function&& f);
`
[21](#func.con-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13910)
*Effects*: Replaces the target of *this with the target of f[.](#func.con-21.sentence-1)
[22](#func.con-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13915)
*Returns*: *this[.](#func.con-22.sentence-1)
[🔗](#lib:operator=,function__)
`function& operator=(nullptr_t) noexcept;
`
[23](#func.con-23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13926)
*Effects*: If *this != nullptr, destroys the target of this[.](#func.con-23.sentence-1)
[24](#func.con-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13930)
*Postconditions*: !(*this)[.](#func.con-24.sentence-1)
[25](#func.con-25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13934)
*Returns*: *this[.](#func.con-25.sentence-1)
[🔗](#lib:operator=,function___)
`template<class F> function& operator=(F&& f);
`
[26](#func.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[.](#func.con-26.sentence-1)
[27](#func.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](#func.con-28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13953)
*Returns*: *this[.](#func.con-28.sentence-1)
[🔗](#lib:operator=,function____)
`template<class F> function& operator=(reference_wrapper<F> f) noexcept;
`
[29](#func.con-29)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13964)
*Effects*: As if by: function(f).swap(*this);
[30](#func.con-30)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13968)
*Returns*: *this[.](#func.con-30.sentence-1)
[🔗](#lib:function,destructor)
`~function();
`
[31](#func.con-31)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13979)
*Effects*: If *this != nullptr, destroys the target of this[.](#func.con-31.sentence-1)
#### [22.10.17.3.3](#func.mod) Modifiers [[func.wrap.func.mod]](func.wrap.func.mod)
[🔗](#lib:swap,function)
`void swap(function& other) noexcept;
`
[1](#func.mod-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13992)
*Effects*: Interchanges the target objects of *this and other[.](#func.mod-1.sentence-1)
#### [22.10.17.3.4](#func.cap) Capacity [[func.wrap.func.cap]](func.wrap.func.cap)
[🔗](#lib:operator_bool,function)
`explicit operator bool() const noexcept;
`
[1](#func.cap-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14005)
*Returns*: true if *this has a target, otherwise false[.](#func.cap-1.sentence-1)
#### [22.10.17.3.5](#func.inv) Invocation [[func.wrap.func.inv]](func.wrap.func.inv)
[🔗](#lib:function,invocation)
`R operator()(ArgTypes... args) const;
`
[1](#func.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[.](#func.inv-1.sentence-1)
[2](#func.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[.](#func.inv-2.sentence-1)
#### [22.10.17.3.6](#func.targ) Target access [[func.wrap.func.targ]](func.wrap.func.targ)
[🔗](#lib:target_type,function)
`const type_info& target_type() const noexcept;
`
[1](#func.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)[.](#func.targ-1.sentence-1)
[🔗](#lib:target,function)
`template<class T> T* target() noexcept;
template<class T> const T* target() const noexcept;
`
[2](#func.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[.](#func.targ-2.sentence-1)
#### [22.10.17.3.7](#func.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](#func.nullptr-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14066)
*Returns*: !f[.](#func.nullptr-1.sentence-1)
#### [22.10.17.3.8](#func.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](#func.alg-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14080)
*Effects*: As if by: f1.swap(f2);
#### [22.10.17.4](#move) Move-only wrapper [[func.wrap.move]](func.wrap.move)
#### [22.10.17.4.1](#move.general) General [[func.wrap.move.general]](func.wrap.move.general)
[1](#move.general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14089)
The header provides partial specializations of move_only_function for each combination of the possible replacements
of the placeholders cv, *ref*, and *noex* where
- [(1.1)](#move.general-1.1)
cv is either const or empty,
- [(1.2)](#move.general-1.2)
*ref* is either &, &&, or empty, and
- [(1.3)](#move.general-1.3)
*noex* is either true or false[.](#move.general-1.sentence-1)
[2](#move.general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14102)
For each of the possible combinations of the placeholders mentioned above,
there is a placeholder *inv-quals* defined as follows:
- [(2.1)](#move.general-2.1)
If *ref* is empty, let *inv-quals* be cv&,
- [(2.2)](#move.general-2.2)
otherwise, let *inv-quals* be cv *ref*[.](#move.general-2.sentence-1)
#### [22.10.17.4.2](#move.class) Class template move_only_function [[func.wrap.move.class]](func.wrap.move.class)
[🔗](#lib:move_only_function)
namespace std {template<class R, class... ArgTypes>class move_only_function<R(ArgTypes...) cv *ref* noexcept(*noex*)> {public:using result_type = R; // [[func.wrap.move.ctor]](#move.ctor "22.10.17.4.3Constructors, assignments, and destructor"), constructors, assignments, and destructor move_only_function() noexcept;
move_only_function(nullptr_t) noexcept;
move_only_function(move_only_function&&) noexcept; template<class F> move_only_function(F&&); template<class T, class... Args>explicit move_only_function(in_place_type_t<T>, Args&&...); template<class T, class U, class... Args>explicit move_only_function(in_place_type_t<T>, initializer_list<U>, Args&&...);
move_only_function& operator=(move_only_function&&);
move_only_function& operator=(nullptr_t) noexcept; template<class F> move_only_function& operator=(F&&); ~move_only_function(); // [[func.wrap.move.inv]](#move.inv "22.10.17.4.4Invocation"), invocationexplicit operator bool() const noexcept;
R operator()(ArgTypes...) cv *ref* noexcept(*noex*); // [[func.wrap.move.util]](#move.util "22.10.17.4.5Utility"), utilityvoid swap(move_only_function&) noexcept; friend void swap(move_only_function&, move_only_function&) noexcept; friend bool operator==(const move_only_function&, nullptr_t) noexcept; private:template<class VT>static constexpr bool *is-callable-from* = *see below*; // *exposition only*};}
[1](#move.class-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14154)
The move_only_function class template provides polymorphic wrappers
that generalize the notion of a callable object ([[func.def]](func.def "22.10.3Definitions"))[.](#move.class-1.sentence-1)
These wrappers can store, move, and call arbitrary callable objects,
given a call signature[.](#move.class-1.sentence-2)
[2](#move.class-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14160)
*Recommended practice*: Implementations should avoid the use of dynamically allocated memory
for a small contained value[.](#move.class-2.sentence-1)
[*Note [1](#move.class-note-1)*:
Such small-object optimization can only be applied to a type T for which is_nothrow_move_constructible_v<T> is true[.](#move.class-2.sentence-2)
— *end note*]
#### [22.10.17.4.3](#move.ctor) Constructors, assignments, and destructor [[func.wrap.move.ctor]](func.wrap.move.ctor)
[🔗](#:move_only_function::is-callable-from)
`template<class VT>
static constexpr bool is-callable-from = see below;
`
[1](#move.ctor-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14178)
If *noex* is true,*is-callable-from*<VT> is equal to:is_nothrow_invocable_r_v<R, VT cv *ref*, ArgTypes...> && is_nothrow_invocable_r_v<R, VT *inv-quals*, ArgTypes...>
Otherwise, *is-callable-from*<VT> is equal to:is_invocable_r_v<R, VT cv *ref*, ArgTypes...> && is_invocable_r_v<R, VT *inv-quals*, ArgTypes...>
[🔗](#lib:move_only_function,constructor)
`move_only_function() noexcept;
move_only_function(nullptr_t) noexcept;
`
[2](#move.ctor-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14199)
*Postconditions*: *this has no target object[.](#move.ctor-2.sentence-1)
[🔗](#lib:move_only_function,constructor_)
`move_only_function(move_only_function&& f) noexcept;
`
[3](#move.ctor-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14210)
*Postconditions*: The target object of *this is
the target object f had before construction, andf is in a valid state with an unspecified value[.](#move.ctor-3.sentence-1)
[🔗](#lib:move_only_function,constructor__)
`template<class F> move_only_function(F&& f);
`
[4](#move.ctor-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14223)
Let VT be decay_t<F>[.](#move.ctor-4.sentence-1)
[5](#move.ctor-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14226)
*Constraints*:
- [(5.1)](#move.ctor-5.1)
remove_cvref_t<F> is not the same type as move_only_function, and
- [(5.2)](#move.ctor-5.2)
remove_cvref_t<F> is not a specialization of in_place_type_t, and
- [(5.3)](#move.ctor-5.3)
*is-callable-from*<VT> is true[.](#move.ctor-5.sentence-1)
[6](#move.ctor-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14237)
*Mandates*: is_constructible_v<VT, F> is true[.](#move.ctor-6.sentence-1)
[7](#move.ctor-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14241)
*Preconditions*: VT meets the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2Template argument requirements[utility.arg.requirements]") requirements, and
if is_move_constructible_v<VT> is true,VT meets the [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2Template argument requirements[utility.arg.requirements]") requirements[.](#move.ctor-7.sentence-1)
[8](#move.ctor-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14247)
*Postconditions*: *this has no target object if any of the following hold:
- [(8.1)](#move.ctor-8.1)
f is a null function pointer value, or
- [(8.2)](#move.ctor-8.2)
f is a null member pointer value, or
- [(8.3)](#move.ctor-8.3)
remove_cvref_t<F> is a specialization of
the move_only_function class template,
and f has no target object[.](#move.ctor-8.sentence-1)
Otherwise, *this has a target object of type VT direct-non-list-initialized with std::forward<F>(f)[.](#move.ctor-8.sentence-2)
[9](#move.ctor-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14263)
*Throws*: Any exception thrown by the initialization of the target object[.](#move.ctor-9.sentence-1)
May throw bad_alloc unless VT is
a function pointer or a specialization of reference_wrapper[.](#move.ctor-9.sentence-2)
[🔗](#lib:move_only_function,constructor___)
`template<class T, class... Args>
explicit move_only_function(in_place_type_t<T>, Args&&... args);
`
[10](#move.ctor-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14277)
Let VT be decay_t<T>[.](#move.ctor-10.sentence-1)
[11](#move.ctor-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14280)
*Constraints*:
- [(11.1)](#move.ctor-11.1)
is_constructible_v<VT, Args...> is true, and
- [(11.2)](#move.ctor-11.2)
*is-callable-from*<VT> is true[.](#move.ctor-11.sentence-1)
[12](#move.ctor-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14289)
*Mandates*: VT is the same type as T[.](#move.ctor-12.sentence-1)
[13](#move.ctor-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14293)
*Preconditions*: VT meets the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2Template argument requirements[utility.arg.requirements]") requirements, and
if is_move_constructible_v<VT> is true,VT meets the [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2Template argument requirements[utility.arg.requirements]") requirements[.](#move.ctor-13.sentence-1)
[14](#move.ctor-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14299)
*Postconditions*: *this has a target object of type VT direct-non-list-initialized with std::forward<Args>(args)...[.](#move.ctor-14.sentence-1)
[15](#move.ctor-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14304)
*Throws*: Any exception thrown by the initialization of the target object[.](#move.ctor-15.sentence-1)
May throw bad_alloc unless VT is
a function pointer or a specialization of reference_wrapper[.](#move.ctor-15.sentence-2)
[🔗](#lib:move_only_function,constructor____)
`template<class T, class U, class... Args>
explicit move_only_function(in_place_type_t<T>, initializer_list<U> ilist, Args&&... args);
`
[16](#move.ctor-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14318)
Let VT be decay_t<T>[.](#move.ctor-16.sentence-1)
[17](#move.ctor-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14321)
*Constraints*:
- [(17.1)](#move.ctor-17.1)
is_constructible_v<VT, initializer_list<U>&, Args...> istrue, and
- [(17.2)](#move.ctor-17.2)
*is-callable-from*<VT> is true[.](#move.ctor-17.sentence-1)
[18](#move.ctor-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14331)
*Mandates*: VT is the same type as T[.](#move.ctor-18.sentence-1)
[19](#move.ctor-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14335)
*Preconditions*: VT meets the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2Template argument requirements[utility.arg.requirements]") requirements, and
if is_move_constructible_v<VT> is true,VT meets the [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2Template argument requirements[utility.arg.requirements]") requirements[.](#move.ctor-19.sentence-1)
[20](#move.ctor-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14341)
*Postconditions*: *this has a target object of type VT direct-non-list-initialized withilist, std::forward<Args>(args)...[.](#move.ctor-20.sentence-1)
[21](#move.ctor-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14347)
*Throws*: Any exception thrown by the initialization of the target object[.](#move.ctor-21.sentence-1)
May throw bad_alloc unless VT is
a function pointer or a specialization of reference_wrapper[.](#move.ctor-21.sentence-2)
[🔗](#lib:operator=,move_only_function)
`move_only_function& operator=(move_only_function&& f);
`
[22](#move.ctor-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14360)
*Effects*: Equivalent to: move_only_function(std::move(f)).swap(*this);
[23](#move.ctor-23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14364)
*Returns*: *this[.](#move.ctor-23.sentence-1)
[🔗](#lib:operator=,move_only_function_)
`move_only_function& operator=(nullptr_t) noexcept;
`
[24](#move.ctor-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14375)
*Effects*: Destroys the target object of *this, if any[.](#move.ctor-24.sentence-1)
[25](#move.ctor-25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14379)
*Returns*: *this[.](#move.ctor-25.sentence-1)
[🔗](#lib:operator=,move_only_function__)
`template<class F> move_only_function& operator=(F&& f);
`
[26](#move.ctor-26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14390)
*Effects*: Equivalent to: move_only_function(std::forward<F>(f)).swap(*this);
[27](#move.ctor-27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14394)
*Returns*: *this[.](#move.ctor-27.sentence-1)
[🔗](#lib:move_only_function,destructor)
`~move_only_function();
`
[28](#move.ctor-28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14405)
*Effects*: Destroys the target object of *this, if any[.](#move.ctor-28.sentence-1)
#### [22.10.17.4.4](#move.inv) Invocation [[func.wrap.move.inv]](func.wrap.move.inv)
[🔗](#lib:operator_bool,move_only_function)
`explicit operator bool() const noexcept;
`
[1](#move.inv-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14418)
*Returns*: true if *this has a target object, otherwise false[.](#move.inv-1.sentence-1)
[🔗](#lib:operator(),move_only_function)
`R operator()(ArgTypes... args) cv ref noexcept(noex);
`
[2](#move.inv-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14429)
*Preconditions*: *this has a target object[.](#move.inv-2.sentence-1)
[3](#move.inv-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14433)
*Effects*: Equivalent to:return *INVOKE*<R>(static_cast<F *inv-quals*>(f), std::forward<ArgTypes>(args)...); where f is an lvalue designating the target object of *this andF is the type of f[.](#move.inv-3.sentence-1)
#### [22.10.17.4.5](#move.util) Utility [[func.wrap.move.util]](func.wrap.move.util)
[🔗](#lib:swap,move_only_function)
`void swap(move_only_function& other) noexcept;
`
[1](#move.util-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14451)
*Effects*: Exchanges the target objects of *this and other[.](#move.util-1.sentence-1)
[🔗](#lib:swap,move_only_function_)
`friend void swap(move_only_function& f1, move_only_function& f2) noexcept;
`
[2](#move.util-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14462)
*Effects*: Equivalent to f1.swap(f2)[.](#move.util-2.sentence-1)
[🔗](#lib:operator==,move_only_function)
`friend bool operator==(const move_only_function& f, nullptr_t) noexcept;
`
[3](#move.util-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14473)
*Returns*: true if f has no target object, otherwise false[.](#move.util-3.sentence-1)
#### [22.10.17.5](#copy) Copyable wrapper [[func.wrap.copy]](func.wrap.copy)
#### [22.10.17.5.1](#copy.general) General [[func.wrap.copy.general]](func.wrap.copy.general)
[1](#copy.general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14482)
The header provides partial specializations of copyable_function for each combination of the possible replacements
of the placeholders cv, *ref*, and *noex* where
- [(1.1)](#copy.general-1.1)
cv is either const or empty,
- [(1.2)](#copy.general-1.2)
*ref* is either &, &&, or empty, and
- [(1.3)](#copy.general-1.3)
*noex* is either true or false[.](#copy.general-1.sentence-1)
[2](#copy.general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14495)
For each of the possible combinations of the placeholders mentioned above,
there is a placeholder *inv-quals* defined as follows:
- [(2.1)](#copy.general-2.1)
If *ref* is empty, let *inv-quals* be cv&,
- [(2.2)](#copy.general-2.2)
otherwise, let *inv-quals* be cv *ref*[.](#copy.general-2.sentence-1)
#### [22.10.17.5.2](#copy.class) Class template copyable_function [[func.wrap.copy.class]](func.wrap.copy.class)
[🔗](#lib:copyable_function)
namespace std {template<class R, class... ArgTypes>class copyable_function<R(ArgTypes...) cv *ref* noexcept(*noex*)> {public:using result_type = R; // [[func.wrap.copy.ctor]](#copy.ctor "22.10.17.5.3Constructors, assignments, and destructor"), constructors, assignments, and destructor copyable_function() noexcept;
copyable_function(nullptr_t) noexcept;
copyable_function(const copyable_function&);
copyable_function(copyable_function&&) noexcept; template<class F> copyable_function(F&&); template<class T, class... Args>explicit copyable_function(in_place_type_t<T>, Args&&...); template<class T, class U, class... Args>explicit copyable_function(in_place_type_t<T>, initializer_list<U>, Args&&...);
copyable_function& operator=(const copyable_function&);
copyable_function& operator=(copyable_function&&);
copyable_function& operator=(nullptr_t) noexcept; template<class F> copyable_function& operator=(F&&); ~copyable_function(); // [[func.wrap.copy.inv]](#copy.inv "22.10.17.5.4Invocation"), invocationexplicit operator bool() const noexcept;
R operator()(ArgTypes...) cv *ref* noexcept(*noex*); // [[func.wrap.copy.util]](#copy.util "22.10.17.5.5Utility"), utilityvoid swap(copyable_function&) noexcept; friend void swap(copyable_function&, copyable_function&) noexcept; friend bool operator==(const copyable_function&, nullptr_t) noexcept; private:template<class VT>static constexpr bool *is-callable-from* = *see below*; // *exposition only*};}
[1](#copy.class-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14549)
The copyable_function class template provides polymorphic wrappers
that generalize the notion of a callable object ([[func.def]](func.def "22.10.3Definitions"))[.](#copy.class-1.sentence-1)
These wrappers can store, copy, move, and call arbitrary callable objects,
given a call signature[.](#copy.class-1.sentence-2)
[2](#copy.class-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14555)
*Recommended practice*: Implementations should avoid the use of dynamically allocated memory
for a small contained value[.](#copy.class-2.sentence-1)
[*Note [1](#copy.class-note-1)*:
Such small-object optimization can only be applied to a type T for which is_nothrow_move_constructible_v<T> is true[.](#copy.class-2.sentence-2)
— *end note*]
#### [22.10.17.5.3](#copy.ctor) Constructors, assignments, and destructor [[func.wrap.copy.ctor]](func.wrap.copy.ctor)
[🔗](#:copyable_function::is-callable-from)
`template<class VT>
static constexpr bool is-callable-from = see below;
`
[1](#copy.ctor-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14573)
If *noex* is true,*is-callable-from*<VT> is equal to:is_nothrow_invocable_r_v<R, VT cv *ref*, ArgTypes...> && is_nothrow_invocable_r_v<R, VT *inv-quals*, ArgTypes...>
Otherwise, *is-callable-from*<VT> is equal to:is_invocable_r_v<R, VT cv *ref*, ArgTypes...> && is_invocable_r_v<R, VT *inv-quals*, ArgTypes...>
[🔗](#lib:copyable_function,constructor)
`copyable_function() noexcept;
copyable_function(nullptr_t) noexcept;
`
[2](#copy.ctor-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14594)
*Postconditions*: *this has no target object[.](#copy.ctor-2.sentence-1)
[🔗](#lib:copyable_function,constructor_)
`copyable_function(const copyable_function& f);
`
[3](#copy.ctor-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14605)
*Postconditions*: *this has no target object if f had no target object[.](#copy.ctor-3.sentence-1)
Otherwise, the target object of *this is a copy of the target object of f[.](#copy.ctor-3.sentence-2)
[4](#copy.ctor-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14611)
*Throws*: Any exception thrown by the initialization of the target object[.](#copy.ctor-4.sentence-1)
May throw bad_alloc[.](#copy.ctor-4.sentence-2)
[🔗](#lib:copyable_function,constructor__)
`copyable_function(copyable_function&& f) noexcept;
`
[5](#copy.ctor-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14623)
*Postconditions*: The target object of *this is
the target object f had before construction, andf is in a valid state with an unspecified value[.](#copy.ctor-5.sentence-1)
[🔗](#lib:copyable_function,constructor___)
`template<class F> copyable_function(F&& f);
`
[6](#copy.ctor-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14636)
Let VT be decay_t<F>[.](#copy.ctor-6.sentence-1)
[7](#copy.ctor-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14639)
*Constraints*:
- [(7.1)](#copy.ctor-7.1)
remove_cvref_t<F> is not the same type as copyable_function, and
- [(7.2)](#copy.ctor-7.2)
remove_cvref_t<F> is not a specialization of in_place_type_t, and
- [(7.3)](#copy.ctor-7.3)
*is-callable-from*<VT> is true[.](#copy.ctor-7.sentence-1)
[8](#copy.ctor-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14650)
*Mandates*:
- [(8.1)](#copy.ctor-8.1)
is_constructible_v<VT, F> is true, and
- [(8.2)](#copy.ctor-8.2)
is_copy_constructible_v<VT> is true[.](#copy.ctor-8.sentence-1)
[9](#copy.ctor-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14659)
*Preconditions*: VT meets the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2Template argument requirements[utility.arg.requirements]") and[*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2Template argument requirements[utility.arg.requirements]") requirements[.](#copy.ctor-9.sentence-1)
[10](#copy.ctor-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14664)
*Postconditions*: *this has no target object if any of the following hold:
- [(10.1)](#copy.ctor-10.1)
f is a null function pointer value, or
- [(10.2)](#copy.ctor-10.2)
f is a null member pointer value, or
- [(10.3)](#copy.ctor-10.3)
remove_cvref_t<F> is a specialization of
the copyable_function class template,
and f has no target object[.](#copy.ctor-10.sentence-1)
Otherwise, *this has a target object of type VT direct-non-list-initialized with std::forward<F>(f)[.](#copy.ctor-10.sentence-2)
[11](#copy.ctor-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14680)
*Throws*: Any exception thrown by the initialization of the target object[.](#copy.ctor-11.sentence-1)
May throw bad_alloc unless VT is
a function pointer or a specialization of reference_wrapper[.](#copy.ctor-11.sentence-2)
[🔗](#lib:copyable_function,constructor____)
`template<class T, class... Args>
explicit copyable_function(in_place_type_t<T>, Args&&... args);
`
[12](#copy.ctor-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14694)
Let VT be decay_t<T>[.](#copy.ctor-12.sentence-1)
[13](#copy.ctor-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14697)
*Constraints*:
- [(13.1)](#copy.ctor-13.1)
is_constructible_v<VT, Args...> is true, and
- [(13.2)](#copy.ctor-13.2)
*is-callable-from*<VT> is true[.](#copy.ctor-13.sentence-1)
[14](#copy.ctor-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14706)
*Mandates*:
- [(14.1)](#copy.ctor-14.1)
VT is the same type as T, and
- [(14.2)](#copy.ctor-14.2)
is_copy_constructible_v<VT> is true[.](#copy.ctor-14.sentence-1)
[15](#copy.ctor-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14715)
*Preconditions*: VT meets the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2Template argument requirements[utility.arg.requirements]") and[*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2Template argument requirements[utility.arg.requirements]") requirements[.](#copy.ctor-15.sentence-1)
[16](#copy.ctor-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14720)
*Postconditions*: *this has a target object of type VT direct-non-list-initialized with std::forward<Args>(args)...[.](#copy.ctor-16.sentence-1)
[17](#copy.ctor-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14725)
*Throws*: Any exception thrown by the initialization of the target object[.](#copy.ctor-17.sentence-1)
May throw bad_alloc unless VT is
a pointer or a specialization of reference_wrapper[.](#copy.ctor-17.sentence-2)
[🔗](#lib:copyable_function,constructor_____)
`template<class T, class U, class... Args>
explicit copyable_function(in_place_type_t<T>, initializer_list<U> ilist, Args&&... args);
`
[18](#copy.ctor-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14739)
Let VT be decay_t<T>[.](#copy.ctor-18.sentence-1)
[19](#copy.ctor-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14742)
*Constraints*:
- [(19.1)](#copy.ctor-19.1)
is_constructible_v<VT, initializer_list<U>&, Args...> istrue, and
- [(19.2)](#copy.ctor-19.2)
*is-callable-from*<VT> is true[.](#copy.ctor-19.sentence-1)
[20](#copy.ctor-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14752)
*Mandates*:
- [(20.1)](#copy.ctor-20.1)
VT is the same type as T, and
- [(20.2)](#copy.ctor-20.2)
is_copy_constructible_v<VT> is true[.](#copy.ctor-20.sentence-1)
[21](#copy.ctor-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14761)
*Preconditions*: VT meets the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2Template argument requirements[utility.arg.requirements]") and[*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2Template argument requirements[utility.arg.requirements]") requirements[.](#copy.ctor-21.sentence-1)
[22](#copy.ctor-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14766)
*Postconditions*: *this has a target object of type VT direct-non-list-initialized withilist, std::forward<Args>(args)...[.](#copy.ctor-22.sentence-1)
[23](#copy.ctor-23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14772)
*Throws*: Any exception thrown by the initialization of the target object[.](#copy.ctor-23.sentence-1)
May throw bad_alloc unless VT is
a pointer or a specialization of reference_wrapper[.](#copy.ctor-23.sentence-2)
[🔗](#lib:operator=,copyable_function)
`copyable_function& operator=(const copyable_function& f);
`
[24](#copy.ctor-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14785)
*Effects*: Equivalent to: copyable_function(f).swap(*this);
[25](#copy.ctor-25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14789)
*Returns*: *this[.](#copy.ctor-25.sentence-1)
[🔗](#lib:operator=,copyable_function_)
`copyable_function& operator=(copyable_function&& f);
`
[26](#copy.ctor-26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14800)
*Effects*: Equivalent to: copyable_function(std::move(f)).swap(*this);
[27](#copy.ctor-27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14804)
*Returns*: *this[.](#copy.ctor-27.sentence-1)
[🔗](#lib:operator=,copyable_function__)
`copyable_function& operator=(nullptr_t) noexcept;
`
[28](#copy.ctor-28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14815)
*Effects*: Destroys the target object of *this, if any[.](#copy.ctor-28.sentence-1)
[29](#copy.ctor-29)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14819)
*Returns*: *this[.](#copy.ctor-29.sentence-1)
[🔗](#lib:operator=,copyable_function___)
`template<class F> copyable_function& operator=(F&& f);
`
[30](#copy.ctor-30)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14830)
*Effects*: Equivalent to: copyable_function(std::forward<F>(f)).swap(*this);
[31](#copy.ctor-31)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14834)
*Returns*: *this[.](#copy.ctor-31.sentence-1)
[🔗](#lib:copyable_function,destructor)
`~copyable_function();
`
[32](#copy.ctor-32)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14845)
*Effects*: Destroys the target object of *this, if any[.](#copy.ctor-32.sentence-1)
#### [22.10.17.5.4](#copy.inv) Invocation [[func.wrap.copy.inv]](func.wrap.copy.inv)
[🔗](#lib:operator_bool,copyable_function)
`explicit operator bool() const noexcept;
`
[1](#copy.inv-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14858)
*Returns*: true if *this has a target object, otherwise false[.](#copy.inv-1.sentence-1)
[🔗](#lib:operator(),copyable_function)
`R operator()(ArgTypes... args) cv ref noexcept(noex);
`
[2](#copy.inv-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14869)
*Preconditions*: *this has a target object[.](#copy.inv-2.sentence-1)
[3](#copy.inv-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14873)
*Effects*: Equivalent to:return *INVOKE*<R>(static_cast<F *inv-quals*>(f), std::forward<ArgTypes>(args)...); where f is an lvalue designating the target object of *this andF is the type of f[.](#copy.inv-3.sentence-1)
#### [22.10.17.5.5](#copy.util) Utility [[func.wrap.copy.util]](func.wrap.copy.util)
[🔗](#lib:swap,copyable_function)
`void swap(copyable_function& other) noexcept;
`
[1](#copy.util-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14891)
*Effects*: Exchanges the target objects of *this and other[.](#copy.util-1.sentence-1)
[🔗](#lib:swap,copyable_function_)
`friend void swap(copyable_function& f1, copyable_function& f2) noexcept;
`
[2](#copy.util-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14902)
*Effects*: Equivalent to f1.swap(f2)[.](#copy.util-2.sentence-1)
[🔗](#lib:operator==,copyable_function)
`friend bool operator==(const copyable_function& f, nullptr_t) noexcept;
`
[3](#copy.util-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14913)
*Returns*: true if f has no target object, otherwise false[.](#copy.util-3.sentence-1)
#### [22.10.17.6](#ref) Non-owning wrapper [[func.wrap.ref]](func.wrap.ref)
#### [22.10.17.6.1](#ref.general) General [[func.wrap.ref.general]](func.wrap.ref.general)
[1](#ref.general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14922)
The header provides partial specializations of function_ref for each combination of the possible replacements of
the placeholders cv and *noex* where:
- [(1.1)](#ref.general-1.1)
cv is either const or empty, and
- [(1.2)](#ref.general-1.2)
*noex* is either true or false[.](#ref.general-1.sentence-1)
#### [22.10.17.6.2](#ref.class) Class template function_ref [[func.wrap.ref.class]](func.wrap.ref.class)
[🔗](#lib:function_ref)
namespace std {template<class R, class... ArgTypes>class function_ref<R(ArgTypes...) cv noexcept(*noex*)> {public:// [[func.wrap.ref.ctor]](#ref.ctor "22.10.17.6.3Constructors and assignment operators"), constructors and assignment operatorstemplate<class F> function_ref(F*) noexcept; template<class F> constexpr function_ref(F&&) noexcept; template<auto f> constexpr function_ref(nontype_t<f>) noexcept; template<auto f, class U> constexpr function_ref(nontype_t<f>, U&&) noexcept; template<auto f, class T> constexpr function_ref(nontype_t<f>, cv T*) noexcept; constexpr function_ref(const function_ref&) noexcept = default; constexpr function_ref& operator=(const function_ref&) noexcept = default; template<class T> function_ref& operator=(T) = delete; // [[func.wrap.ref.inv]](#ref.inv "22.10.17.6.4Invocation"), invocation R operator()(ArgTypes...) const noexcept(*noex*); private:template<class... T>static constexpr bool *is-invocable-using* = *see below*; // *exposition only* R (**thunk-ptr*)(*BoundEntityType*, Args&&...) noexcept(*noex*); // *exposition only**BoundEntityType* *bound-entity*; // *exposition only*}; // [[func.wrap.ref.deduct]](#ref.deduct "22.10.17.6.5Deduction guides"), deduction guidestemplate<class F> function_ref(F*) -> function_ref<F>; template<auto f> function_ref(nontype_t<f>) -> function_ref<*see below*>; template<auto f, class T> function_ref(nontype_t<f>, T&&) -> function_ref<*see below*>;}
[1](#ref.class-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14971)
An object of classfunction_ref<R(Args...) cv noexcept(*noex*)> stores a pointer to function *thunk-ptr* and
an object *bound-entity*[.](#ref.class-1.sentence-1)
*bound-entity* has
an unspecified trivially copyable type *BoundEntityType*, that
models [copyable](concepts.object#concept:copyable "18.6Object concepts[concepts.object]") and
is capable of storing a pointer to object value or a pointer to function value[.](#ref.class-1.sentence-2)
The type of *thunk-ptr* isR(*)(*BoundEntityType*, Args&&...) noexcept(*noex*)[.](#ref.class-1.sentence-3)
[2](#ref.class-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14983)
Each specialization of function_ref is
a trivially copyable type ([[basic.types.general]](basic.types.general#term.trivially.copyable.type "6.9.1General"))
that models [copyable](concepts.object#concept:copyable "18.6Object concepts[concepts.object]")[.](#ref.class-2.sentence-1)
[3](#ref.class-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14988)
Within [[func.wrap.ref]](#ref "22.10.17.6Non-owning wrapper"),*call-args* is an argument pack with elements such thatdecltype((*call-args*))... denoteArgs&&... respectively[.](#ref.class-3.sentence-1)
#### [22.10.17.6.3](#ref.ctor) Constructors and assignment operators [[func.wrap.ref.ctor]](func.wrap.ref.ctor)
[🔗](#:function_ref::is-invocable-using)
`template<class... T>
static constexpr bool is-invocable-using = see below;
`
[1](#ref.ctor-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15003)
If *noex* is true,*is-invocable-using*<T...> is equal to:is_nothrow_invocable_r_v<R, T..., ArgTypes...>
Otherwise, *is-invocable-using*<T...> is equal to:is_invocable_r_v<R, T..., ArgTypes...>
[🔗](#lib:function_ref,constructor)
`template<class F> function_ref(F* f) noexcept;
`
[2](#ref.ctor-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15021)
*Constraints*:
- [(2.1)](#ref.ctor-2.1)
is_function_v<F> is true, and
- [(2.2)](#ref.ctor-2.2)
*is-invocable-using*<F> is true[.](#ref.ctor-2.sentence-1)
[3](#ref.ctor-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15028)
*Preconditions*: f is not a null pointer[.](#ref.ctor-3.sentence-1)
[4](#ref.ctor-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15032)
*Effects*: Initializes*bound-entity* with f, and*thunk-ptr* with the address of a function *thunk* such that*thunk*(*bound-entity*, *call-args*...) is expression-equivalent ([[defns.expression.equivalent]](defns.expression.equivalent "3.22expression-equivalent")) toinvoke_r<R>(f, *call-args*...)[.](#ref.ctor-4.sentence-1)
[🔗](#lib:function_ref,constructor_)
`template<class F> constexpr function_ref(F&& f) noexcept;
`
[5](#ref.ctor-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15049)
Let T be remove_reference_t<F>[.](#ref.ctor-5.sentence-1)
[6](#ref.ctor-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15052)
*Constraints*:
- [(6.1)](#ref.ctor-6.1)
remove_cvref_t<F> is not the same type as function_ref,
- [(6.2)](#ref.ctor-6.2)
is_member_pointer_v<T> is false, and
- [(6.3)](#ref.ctor-6.3)
*is-invocable-using*<cv T&> is true[.](#ref.ctor-6.sentence-1)
[7](#ref.ctor-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15060)
*Effects*: Initializes*bound-entity* with addressof(f), and*thunk-ptr* with the address of a function *thunk* such that*thunk*(*bound-entity*, *call-args*...) is expression-equivalent ([[defns.expression.equivalent]](defns.expression.equivalent "3.22expression-equivalent")) toinvoke_r<R>(static_cast<cv T&>(f), *call-args*...)[.](#ref.ctor-7.sentence-1)
[🔗](#lib:function_ref,constructor__)
`template<auto f> constexpr function_ref(nontype_t<f>) noexcept;
`
[8](#ref.ctor-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15077)
Let F be decltype(f)[.](#ref.ctor-8.sentence-1)
[9](#ref.ctor-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15080)
*Constraints*: *is-invocable-using*<F> is true[.](#ref.ctor-9.sentence-1)
[10](#ref.ctor-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15084)
*Mandates*: If is_pointer_v<F> || is_member_pointer_v<F> is true,
then f != nullptr is true[.](#ref.ctor-10.sentence-1)
[11](#ref.ctor-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15089)
*Effects*: Initializes*bound-entity* with a pointer to an unspecified object or
null pointer value, and*thunk-ptr* with the address of a function *thunk* such that*thunk*(*bound-entity*, *call-args*...) is expression-equivalent ([[defns.expression.equivalent]](defns.expression.equivalent "3.22expression-equivalent")) toinvoke_r<R>(f, *call-args*...)[.](#ref.ctor-11.sentence-1)
[🔗](#lib:function_ref,constructor___)
`template<auto f, class U>
constexpr function_ref(nontype_t<f>, U&& obj) noexcept;
`
[12](#ref.ctor-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15108)
Let T be remove_reference_t<U> andF be decltype(f)[.](#ref.ctor-12.sentence-1)
[13](#ref.ctor-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15112)
*Constraints*:
- [(13.1)](#ref.ctor-13.1)
is_rvalue_reference_v<U&&> is false, and
- [(13.2)](#ref.ctor-13.2)
*is-invocable-using*<F, cv T&> is true[.](#ref.ctor-13.sentence-1)
[14](#ref.ctor-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15119)
*Mandates*: If is_pointer_v<F> || is_member_pointer_v<F> is true,
then f != nullptr is true[.](#ref.ctor-14.sentence-1)
[15](#ref.ctor-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15124)
*Effects*: Initializes*bound-entity* with addressof(obj), and*thunk-ptr* with the address of a function *thunk* such that*thunk*(*bound-entity*, *call-args*...) is expression-equivalent ([[defns.expression.equivalent]](defns.expression.equivalent "3.22expression-equivalent")) toinvoke_r<R>(f, static_cast<cv T&>(obj), *call-args*...)[.](#ref.ctor-15.sentence-1)
[🔗](#lib:function_ref,constructor____)
`template<auto f, class T>
constexpr function_ref(nontype_t<f>, cv T* obj) noexcept;
`
[16](#ref.ctor-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15142)
Let F be decltype(f)[.](#ref.ctor-16.sentence-1)
[17](#ref.ctor-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15145)
*Constraints*: *is-invocable-using*<F, cv T*> is true[.](#ref.ctor-17.sentence-1)
[18](#ref.ctor-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15149)
*Mandates*: If is_pointer_v<F> || is_member_pointer_v<F> is true,
then f != nullptr is true[.](#ref.ctor-18.sentence-1)
[19](#ref.ctor-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15154)
*Preconditions*: If is_member_pointer_v<F> is true,obj is not a null pointer[.](#ref.ctor-19.sentence-1)
[20](#ref.ctor-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15159)
*Effects*: Initializes*bound-entity* with obj, and*thunk-ptr* with the address of a function *thunk* such that*thunk*(*bound-entity*, *call-args*...) is expression-equivalent ([[defns.expression.equivalent]](defns.expression.equivalent "3.22expression-equivalent")) toinvoke_r<R>(f, obj, *call-args*...)[.](#ref.ctor-20.sentence-1)
[🔗](#lib:operator=,function_ref)
`template<class T> function_ref& operator=(T) = delete;
`
[21](#ref.ctor-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15176)
*Constraints*:
- [(21.1)](#ref.ctor-21.1)
T is not the same type as function_ref,
- [(21.2)](#ref.ctor-21.2)
is_pointer_v<T> is false, and
- [(21.3)](#ref.ctor-21.3)
T is not a specialization of nontype_t[.](#ref.ctor-21.sentence-1)
#### [22.10.17.6.4](#ref.inv) Invocation [[func.wrap.ref.inv]](func.wrap.ref.inv)
[🔗](#lib:operator(),function_ref)
`R operator()(ArgTypes... args) const noexcept(noex);
`
[1](#ref.inv-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15193)
*Effects*: Equivalent to:return *thunk-ptr*(*bound-entity*, std::forward<ArgTypes>(args)...);
#### [22.10.17.6.5](#ref.deduct) Deduction guides [[func.wrap.ref.deduct]](func.wrap.ref.deduct)
[🔗](#ref.deduct-itemdecl:1)
`template<class F>
function_ref(F*) -> function_ref<F>;
`
[1](#ref.deduct-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15207)
*Constraints*: is_function_v<F> is true[.](#ref.deduct-1.sentence-1)
[🔗](#ref.deduct-itemdecl:2)
`template<auto f>
function_ref(nontype_t<f>) -> function_ref<see below>;
`
[2](#ref.deduct-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15218)
Let F be remove_pointer_t<decltype(f)>[.](#ref.deduct-2.sentence-1)
[3](#ref.deduct-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15221)
*Constraints*: is_function_v<F> is true[.](#ref.deduct-3.sentence-1)
[4](#ref.deduct-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15225)
*Remarks*: The deduced type is function_ref<F>[.](#ref.deduct-4.sentence-1)
[🔗](#ref.deduct-itemdecl:3)
`template<auto f, class T>
function_ref(nontype_t<f>, T&&) -> function_ref<see below>;
`
[5](#ref.deduct-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15236)
Let F be decltype(f)[.](#ref.deduct-5.sentence-1)
[6](#ref.deduct-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15239)
*Constraints*:
- [(6.1)](#ref.deduct-6.1)
F is of the formR(G::*)(A...) cv &opt noexcept(E) for a type G, or
- [(6.2)](#ref.deduct-6.2)
F is of the formM G::* for a type G and an object type M,
in which case
let R be invoke_result_t<F, T&>,A... be an empty pack, andE be false, or
- [(6.3)](#ref.deduct-6.3)
F is of the formR(*)(G, A...) noexcept(E) for a type G[.](#ref.deduct-6.sentence-1)
[7](#ref.deduct-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15259)
*Remarks*: The deduced type is function_ref<R(A...) noexcept(E)>[.](#ref.deduct-7.sentence-1)