[func.wrap.ref]

# 22 General utilities library [[utilities]](./#utilities)

## 22.10 Function objects [[function.objects]](function.objects#func.wrap.ref)

### 22.10.17 Polymorphic function wrappers [[func.wrap]](func.wrap#ref)

#### 22.10.17.6 Non-owning wrapper [func.wrap.ref]

#### [22.10.17.6.1](#general) General [[func.wrap.ref.general]](func.wrap.ref.general)

[1](#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)](#general-1.1)

cv is either const or empty, and

- [(1.2)](#general-1.2)

*noex* is either true or false[.](#general-1.sentence-1)

#### [22.10.17.6.2](#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]](#ctor "22.10.17.6.3 Constructors 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]](#inv "22.10.17.6.4 Invocation"), 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]](#deduct "22.10.17.6.5 Deduction 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](#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*[.](#class-1.sentence-1)

*bound-entity* has
an unspecified trivially copyable type *BoundEntityType*, that
models [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]") and
is capable of storing a pointer to object value or a pointer to function value[.](#class-1.sentence-2)

The type of *thunk-ptr* isR(*)(*BoundEntityType*, Args&&...) noexcept(*noex*)[.](#class-1.sentence-3)

[2](#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.1 General"))
that models [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]")[.](#class-2.sentence-1)

[3](#class-3)

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

Within [func.wrap.ref],*call-args* is an argument pack with elements such thatdecltype((*call-args*))... denoteArgs&&... respectively[.](#class-3.sentence-1)

#### [22.10.17.6.3](#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](#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](#ctor-2)

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

*Constraints*: 

- [(2.1)](#ctor-2.1)

is_function_v<F> is true, and

- [(2.2)](#ctor-2.2)

*is-invocable-using*<F> is true[.](#ctor-2.sentence-1)

[3](#ctor-3)

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

*Preconditions*: f is not a null pointer[.](#ctor-3.sentence-1)

[4](#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.22 expression-equivalent")) toinvoke_r<R>(f, *call-args*...)[.](#ctor-4.sentence-1)

[ð](#lib:function_ref,constructor_)

`template<class F> constexpr function_ref(F&& f) noexcept;
`

[5](#ctor-5)

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

Let T be remove_reference_t<F>[.](#ctor-5.sentence-1)

[6](#ctor-6)

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

*Constraints*: 

- [(6.1)](#ctor-6.1)

remove_cvref_t<F> is not the same type as function_ref,

- [(6.2)](#ctor-6.2)

is_member_pointer_v<T> is false, and

- [(6.3)](#ctor-6.3)

*is-invocable-using*<cv T&> is true[.](#ctor-6.sentence-1)

[7](#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.22 expression-equivalent")) toinvoke_r<R>(static_cast<cv T&>(f), *call-args*...)[.](#ctor-7.sentence-1)

[ð](#lib:function_ref,constructor__)

`template<auto f> constexpr function_ref(nontype_t<f>) noexcept;
`

[8](#ctor-8)

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

Let F be decltype(f)[.](#ctor-8.sentence-1)

[9](#ctor-9)

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

*Constraints*: *is-invocable-using*<F> is true[.](#ctor-9.sentence-1)

[10](#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[.](#ctor-10.sentence-1)

[11](#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.22 expression-equivalent")) toinvoke_r<R>(f, *call-args*...)[.](#ctor-11.sentence-1)

[ð](#lib:function_ref,constructor___)

`template<auto f, class U>
  constexpr function_ref(nontype_t<f>, U&& obj) noexcept;
`

[12](#ctor-12)

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

Let T be remove_reference_t<U> andF be decltype(f)[.](#ctor-12.sentence-1)

[13](#ctor-13)

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

*Constraints*: 

- [(13.1)](#ctor-13.1)

is_rvalue_reference_v<U&&> is false, and

- [(13.2)](#ctor-13.2)

*is-invocable-using*<F, cv T&> is true[.](#ctor-13.sentence-1)

[14](#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[.](#ctor-14.sentence-1)

[15](#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.22 expression-equivalent")) toinvoke_r<R>(f, static_cast<cv T&>(obj), *call-args*...)[.](#ctor-15.sentence-1)

[ð](#lib:function_ref,constructor____)

`template<auto f, class T>
  constexpr function_ref(nontype_t<f>, cv T* obj) noexcept;
`

[16](#ctor-16)

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

Let F be decltype(f)[.](#ctor-16.sentence-1)

[17](#ctor-17)

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

*Constraints*: *is-invocable-using*<F, cv T*> is true[.](#ctor-17.sentence-1)

[18](#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[.](#ctor-18.sentence-1)

[19](#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[.](#ctor-19.sentence-1)

[20](#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.22 expression-equivalent")) toinvoke_r<R>(f, obj, *call-args*...)[.](#ctor-20.sentence-1)

[ð](#lib:operator=,function_ref)

`template<class T> function_ref& operator=(T) = delete;
`

[21](#ctor-21)

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

*Constraints*: 

- [(21.1)](#ctor-21.1)

T is not the same type as function_ref,

- [(21.2)](#ctor-21.2)

is_pointer_v<T> is false, and

- [(21.3)](#ctor-21.3)

T is not a specialization of nontype_t[.](#ctor-21.sentence-1)

#### [22.10.17.6.4](#inv) Invocation [[func.wrap.ref.inv]](func.wrap.ref.inv)

[ð](#lib:operator(),function_ref)

`R operator()(ArgTypes... args) const noexcept(noex);
`

[1](#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](#deduct) Deduction guides [[func.wrap.ref.deduct]](func.wrap.ref.deduct)

[ð](#deduct-itemdecl:1)

`template<class F>
  function_ref(F*) -> function_ref<F>;
`

[1](#deduct-1)

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

*Constraints*: is_function_v<F> is true[.](#deduct-1.sentence-1)

[ð](#deduct-itemdecl:2)

`template<auto f>
  function_ref(nontype_t<f>) -> function_ref<see below>;
`

[2](#deduct-2)

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

Let F be remove_pointer_t<decltype(f)>[.](#deduct-2.sentence-1)

[3](#deduct-3)

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

*Constraints*: is_function_v<F> is true[.](#deduct-3.sentence-1)

[4](#deduct-4)

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

*Remarks*: The deduced type is function_ref<F>[.](#deduct-4.sentence-1)

[ð](#deduct-itemdecl:3)

`template<auto f, class T>
  function_ref(nontype_t<f>, T&&) -> function_ref<see below>;
`

[5](#deduct-5)

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

Let F be decltype(f)[.](#deduct-5.sentence-1)

[6](#deduct-6)

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

*Constraints*: 

- [(6.1)](#deduct-6.1)

F is of the formR(G​::​*)(A...) cv &opt noexcept(E) for a type G, or

- [(6.2)](#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)](#deduct-6.3)

F is of the formR(*)(G, A...) noexcept(E) for a type G[.](#deduct-6.sentence-1)

[7](#deduct-7)

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

*Remarks*: The deduced type is function_ref<R(A...) noexcept(E)>[.](#deduct-7.sentence-1)
