22 General utilities library [utilities]

22.10 Function objects [function.objects]

22.10.17 Polymorphic function wrappers [func.wrap]

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


22.10.17.6.1 General [func.wrap.ref.general]

22.10.17.6.2 Class template function_ref [func.wrap.ref.class]

22.10.17.6.3 Constructors and assignment operators [func.wrap.ref.ctor]

22.10.17.6.4 Invocation [func.wrap.ref.inv]

22.10.17.6.5 Deduction guides [func.wrap.ref.deduct]


22.10.17.6.1 General [func.wrap.ref.general]

The header provides partial specializations of function_ref for each combination of the possible replacements of the placeholders cv and noex where:
  • cv is either const or empty, and
  • noex is either true or false.

22.10.17.6.2 Class template function_ref [func.wrap.ref.class]

namespace std { template<class R, class... ArgTypes> class function_ref<R(ArgTypes...) cv noexcept(noex)> { public: // [func.wrap.ref.ctor], constructors and assignment operators template<class F> function_ref(F*) noexcept; template<class F> constexpr function_ref(F&&) noexcept; template<auto c, class F> constexpr function_ref(constant_wrapper<c, F>) noexcept; template<auto c, class F, class U> constexpr function_ref(constant_wrapper<c, F>, U&&) noexcept; template<auto c, class F, class T> constexpr function_ref(constant_wrapper<c, 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], 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, ArgTypes&&...) noexcept(noex); // exposition only BoundEntityType bound-entity; // exposition only }; // [func.wrap.ref.deduct], deduction guides template<class F> function_ref(F*) -> function_ref<F>; template<auto c, class F0> function_ref(constant_wrapper<c, F0>) -> function_ref<see below>; template<auto c, class F, class T> function_ref(constant_wrapper<c, F>, T&&) -> function_ref<see below>; }
An object of class function_ref<R(Args...) cv noexcept(noex)> stores a pointer to function thunk-ptr and an object bound-entity.
The object bound-entity has an unspecified trivially copyable type BoundEntityType, that models copyable and is capable of storing a pointer to object value or a pointer to function value.
The type of thunk-ptr is R(*)(BoundEntityType, Args&&...) noexcept(noex).
Each specialization of function_ref is a trivially copyable type ([basic.types.general]) that models copyable.
Within subclause [func.wrap.ref], call-args is an argument pack with elements such that decltype((call-args))... denote ArgTypes&&... respectively.

22.10.17.6.3 Constructors and assignment operators [func.wrap.ref.ctor]

template<class... T> static constexpr bool is-invocable-using = see below;
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...>
template<class F> static constexpr bool is-convertible-from-specialization = see below;
If F denotes a specialization function_ref<R(Args...) cv2 noexcept(noex2)> for some placeholders cv2 and noex2, is-convertible-from-specialization<F> is equal to: is_convertible_v<R(&)(Args...) noexcept(noex2), R(&)(Args...) noexcept(noex)> && is_convertible_v<int cv&, int cv2&>.
Otherwise, is-convertible-from-specialization<F> is false.
template<class F> function_ref(F* f) noexcept;
Constraints:
  • is_function_v<F> is true, and
  • is-invocable-using<F> is true.
Preconditions: f is not a null pointer.
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]) to invoke_r<R>(f, call-args...).
template<class F> constexpr function_ref(F&& f) noexcept;
Let T be remove_reference_t<F>.
Constraints:
  • remove_cvref_t<F> is not the same type as function_ref,
  • is_member_pointer_v<T> is false, and
  • is-invocable-using<cv T&> is true.
Effects: If is-convertible-from-specialization<remove_cv_t<T>> is false, 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]) to invoke_r<R>(static_cast<cv T&>(f), call-args...).
Otherwise, initializes bound-entity with the value of f.bound-entity and thunk-​ptr with the value of f.thunk-ptr.
Remarks: If remove_cvref_t<F> is a specialization of function_ref, an implementation may initialize bound-entity with the value of f.bound-entity and thunk-ptr with the value of f.thunk-ptr.
[Example 1: void f1(std::string); void f2(std::string); function_ref<void(std::string)> r1(&f1); function_ref<void(std::string&&)> r2(r1); r2(""); // f1 is invoked r1 = &f2; r2(""); // it is unspecified if f1 or f2 is invoked — end example]
template<auto c, class F> constexpr function_ref(constant_wrapper<c, F> f) noexcept;
Constraints: is-invocable-using<const F&> is true.
Mandates:
  • If is_pointer_v<F> || is_member_pointer_v<F> is true, then f.value != nullptr is true, and
  • if ArgTypes is not an empty pack and all types in remove_cvref_t<ArgTypes>... satisfy constexpr-param then constant_wrapper<INVOKE(f.value, remove_cvref_t<ArgTypes>​::​
    value...)>
    is not a valid type.
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]) to invoke_r<R>(f.value, call-args...).
template<auto c, class F, class U> constexpr function_ref(constant_wrapper<c, F> f, U&& obj) noexcept;
Let T be remove_reference_t<U>.
Constraints:
  • is_rvalue_reference_v<U&&> is false, and
  • is-invocable-using<const F&, cv T&> is true.
Mandates: If is_pointer_v<F> || is_member_pointer_v<F> is true, then f.value != nullptr is true.
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]) to invoke_r<R>(f.value, static_cast<cv T&>(obj), call-args...).
template<auto c, class F> constexpr function_ref(constant_wrapper<c, F> f, cv T* obj) noexcept;
Constraints: is-invocable-using<const F&, cv T*> is true.
Mandates: If is_pointer_v<F> || is_member_pointer_v<F> is true, then f.value != nullptr is true.
Preconditions: If is_member_pointer_v<F> is true, obj is not a null pointer.
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]) to invoke_r<R>(f.value, obj, call-args...).
template<class T> function_ref& operator=(T) = delete;
Constraints:
  • is-convertible-from-specialization<T> is false,
  • is_pointer_v<T> is false, and
  • T is not a specialization of constant_wrapper.

22.10.17.6.4 Invocation [func.wrap.ref.inv]

R operator()(ArgTypes... args) const noexcept(noex);
Effects: Equivalent to: return thunk-ptr(bound-entity, std​::​forward<ArgTypes>(args)...);

22.10.17.6.5 Deduction guides [func.wrap.ref.deduct]

template<class F> function_ref(F*) -> function_ref<F>;
Constraints: is_function_v<F> is true.
template<auto c, class F0> function_ref(constant_wrapper<c, F0>) -> function_ref<see below>;
Let F be remove_pointer_t<F0>.
Constraints: is_function_v<F> is true.
Remarks: The deduced type is function_ref<F>.
template<auto c, class F, class T> function_ref(constant_wrapper<c, F>, T&&) -> function_ref<see below>;
Constraints:
  • F is of the form R(G​::​*)(A...) cv & noexcept(E) for a type G, or
  • F is of the form M 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, and E be true, or
  • F is of the form R(*)(G, A...) noexcept(E) for a type G.
Remarks: The deduced type is function_ref<R(A...) noexcept(E)>.