20 General utilities library [utilities]

20.14 Function objects [function.objects]

20.14.17 Polymorphic function wrappers [func.wrap]

20.14.17.1 General [func.wrap.general]

Subclause [func.wrap] describes polymorphic wrapper classes that encapsulate arbitrary callable objects.

20.14.17.2 Class bad_­function_­call [func.wrap.badcall]

An exception of type bad_­function_­call is thrown by function​::​operator() ([func.wrap.func.inv]) when the function wrapper object has no target.
namespace std { class bad_function_call : public exception { public: // see [exception] for the specification of the special member functions const char* what() const noexcept override; }; }
const char* what() const noexcept override;
Returns: An implementation-defined ntbs.

20.14.17.3 Class template function [func.wrap.func]

20.14.17.3.1 General [func.wrap.func.general]

namespace std { template<class> class function; // not defined template<class R, class... ArgTypes> class function<R(ArgTypes...)> { public: using result_type = R; // [func.wrap.func.con], 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], function modifiers void swap(function&) noexcept; // [func.wrap.func.cap], function capacity explicit operator bool() const noexcept; // [func.wrap.func.inv], function invocation R operator()(ArgTypes...) const; // [func.wrap.func.targ], function target access const 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>; }
The function class template provides polymorphic wrappers that generalize the notion of a function pointer.
Wrappers can store, copy, and call arbitrary callable objects, given a call signature, allowing functions to be first-class objects.
A callable type F is Lvalue-Callable for argument types ArgTypes and return type R if the expression INVOKE<R>(declval<F&>(), declval<ArgTypes>()...), considered as an unevaluated operand ([term.unevaluated.operand]), is well-formed ([func.require]).
The function class template is a call wrapper whose call signature is R(ArgTypes...).
[Note 1:
The types deduced by the deduction guides for function might change in future revisions of C++.
— end note]

20.14.17.3.2 Constructors and destructor [func.wrap.func.con]

function() noexcept;
Postconditions: !*this.
function(nullptr_t) noexcept;
Postconditions: !*this.
function(const function& f);
Postconditions: !*this if !f; otherwise, the target object of *this is a copy of f.target().
Throws: Nothing if f's target is a specialization of reference_­wrapper or a function pointer.
Otherwise, may throw bad_­alloc or any exception thrown by the copy constructor of the stored callable object.
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.
function(function&& f) noexcept;
Postconditions: If !f, *this has no target; otherwise, the target of *this is equivalent to the target of f before the construction, and f is in a valid state with an unspecified value.
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.
template<class F> function(F&& f);
Let FD be decay_­t<F>.
Constraints:
  • is_­same_­v<remove_­cvref_­t<F>, function> is false, and
  • FD is Lvalue-Callable ([func.wrap.func]) for argument types ArgTypes... and return type R.
Mandates:
  • is_­copy_­constructible_­v<FD> is true, and
  • is_­constructible_­v<FD, F> is true.
Preconditions: FD meets the Cpp17CopyConstructible requirements.
Postconditions: !*this is true if any of the following hold:
  • f is a null function pointer value.
  • f is a null member pointer value.
  • remove_­cvref_­t<F> is a specialization of the function class template, and !f is true.
Otherwise, *this has a target object of type FD direct-non-list-initialized with std​::​forward<F>(f).
Throws: Nothing if FD is a specialization of reference_­wrapper or a function pointer type.
Otherwise, may throw bad_­alloc or any exception thrown by the initialization of the target object.
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.
template<class F> function(F) -> function<see below>;
Constraints: &F​::​operator() is well-formed when treated as an unevaluated operand and decltype(&F​::​operator()) is of the form R(G​::​*)(A...) cv & noexcept for a class type G.
Remarks: The deduced type is function<R(A...)>.
[Example 1: void f() { int i{5}; function g = [&](double) { return i; }; // deduces function<int(double)> } — end example]
function& operator=(const function& f);
Effects: As if by function(f).swap(*this);
Returns: *this.
function& operator=(function&& f);
Effects: Replaces the target of *this with the target of f.
Returns: *this.
function& operator=(nullptr_t) noexcept;
Effects: If *this != nullptr, destroys the target of this.
Postconditions: !(*this).
Returns: *this.
template<class F> function& operator=(F&& f);
Constraints: decay_­t<F> is Lvalue-Callable ([func.wrap.func]) for argument types ArgTypes... and return type R.
Effects: As if by: function(std​::​forward<F>(f)).swap(*this);
Returns: *this.
template<class F> function& operator=(reference_wrapper<F> f) noexcept;
Effects: As if by: function(f).swap(*this);
Returns: *this.
~function();
Effects: If *this != nullptr, destroys the target of this.

20.14.17.3.3 Modifiers [func.wrap.func.mod]

void swap(function& other) noexcept;
Effects: Interchanges the target objects of *this and other.

20.14.17.3.4 Capacity [func.wrap.func.cap]

explicit operator bool() const noexcept;
Returns: true if *this has a target, otherwise false.

20.14.17.3.5 Invocation [func.wrap.func.inv]

R operator()(ArgTypes... args) const;
Returns: INVOKE<R>(f, std​::​forward<ArgTypes>(args)...) ([func.require]), where f is the target object ([func.def]) of *this.
Throws: bad_­function_­call if !*this; otherwise, any exception thrown by the target object.

20.14.17.3.6 Target access [func.wrap.func.targ]

const type_info& target_type() const noexcept;
Returns: If *this has a target of type T, typeid(T); otherwise, typeid(void).
template<class T> T* target() noexcept; template<class T> const T* target() const noexcept;
Returns: If target_­type() == typeid(T) a pointer to the stored function target; otherwise a null pointer.

20.14.17.3.7 Null pointer comparison operator functions [func.wrap.func.nullptr]

template<class R, class... ArgTypes> bool operator==(const function<R(ArgTypes...)>& f, nullptr_t) noexcept;
Returns: !f.

20.14.17.3.8 Specialized algorithms [func.wrap.func.alg]

template<class R, class... ArgTypes> void swap(function<R(ArgTypes...)>& f1, function<R(ArgTypes...)>& f2) noexcept;
Effects: As if by: f1.swap(f2);

20.14.17.4 Move only wrapper [func.wrap.move]

20.14.17.4.1 General [func.wrap.move.general]

The header provides partial specializations of move_­only_­function for each combination of the possible replacements of the placeholders cv, ref, and noex where
  • cv is either const or empty,
  • ref is either &, &&, or empty, and
  • noex is either true or false.
For each of the possible combinations of the placeholders mentioned above, there is a placeholder inv-quals defined as follows:
  • If ref is empty, let inv-quals be cv&,
  • otherwise, let inv-quals be cv ref.

20.14.17.4.2 Class template move_­only_­function [func.wrap.move.class]

namespace std { template<class... S> class move_only_function; // not defined template<class R, class... ArgTypes> class move_only_function<R(ArgTypes...) cv ref noexcept(noex)> { public: using result_type = R; // [func.wrap.move.ctor], constructors, assignment, 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], invocation explicit operator bool() const noexcept; R operator()(ArgTypes...) cv ref noexcept(noex); // [func.wrap.move.util], utility void 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 }; }
The move_­only_­function class template provides polymorphic wrappers that generalize the notion of a callable object ([func.def]).
These wrappers can store, move, and call arbitrary callable objects, given a call signature, allowing functions to be first-class objects.
Recommended practice: Implementations should avoid the use of dynamically allocated memory for a small contained value.
[Note 1:
Such small-object optimization can only be applied to a type T for which is_­nothrow_­move_­constructible_­v<T> is true.
— end note]

20.14.17.4.3 Constructors, assignment, and destructor [func.wrap.move.ctor]

template<class VT> static constexpr bool is-callable-from = see below;
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...>
move_only_function() noexcept; move_only_function(nullptr_t) noexcept;
Postconditions: *this has no target object.
move_only_function(move_only_function&& f) noexcept;
Postconditions: The target object of *this is the target object f had before construction, and f is in a valid state with an unspecified value.
template<class F> move_only_function(F&& f);
Let VT be decay_­t<F>.
Constraints:
  • remove_­cvref_­t<F> is not the same type as move_­only_­function, and
  • remove_­cvref_­t<F> is not a specialization of in_­place_­type_­t, and
  • is-callable-from<VT> is true.
Mandates: is_­constructible_­v<VT, F> is true.
Preconditions: VT meets the Cpp17Destructible requirements, and if is_­move_­constructible_­v<VT> is true, VT meets the Cpp17MoveConstructible requirements.
Postconditions: *this has no target object if any of the following hold:
  • f is a null function pointer value, or
  • f is a null member pointer value, or
  • remove_­cvref_­t<F> is a specialization of the move_­only_­function class template, and f has no target object.
Otherwise, *this has a target object of type VT direct-non-list-initialized with std​::​forward<F>(f).
Throws: Any exception thrown by the initialization of the target object.
May throw bad_­alloc unless VT is a function pointer or a specialization of reference_­wrapper.
template<class T, class... Args> explicit move_only_function(in_place_type_t<T>, Args&&... args);
Let VT be decay_­t<T>.
Constraints:
  • is_­constructible_­v<VT, Args...> is true, and
  • is-callable-from<VT> is true.
Mandates: VT is the same type as T.
Preconditions: VT meets the Cpp17Destructible requirements, and if is_­move_­constructible_­v<VT> is true, VT meets the Cpp17MoveConstructible requirements.
Postconditions: *this has a target object of type VT direct-non-list-initialized with std​::​forward<Args>(args)....
Throws: Any exception thrown by the initialization of the target object.
May throw bad_­alloc unless VT is a function pointer or a specialization of reference_­wrapper.
template<class T, class U, class... Args> explicit move_only_function(in_place_type_t<T>, initializer_list<U> ilist, Args&&... args);
Let VT be decay_­t<T>.
Constraints:
  • is_­constructible_­v<VT, initializer_­list<U>&, ArgTypes...> is true, and
  • is-callable-from<VT> is true.
Mandates: VT is the same type as T.
Preconditions: VT meets the Cpp17Destructible requirements, and if is_­move_­constructible_­v<VT> is true, VT meets the Cpp17MoveConstructible requirements.
Postconditions: *this has a target object of type VT direct-non-list-initialized with ilist, std​::​forward<ArgTypes>(args)....
Throws: Any exception thrown by the initialization of the target object.
May throw bad_­alloc unless VT is a function pointer or a specialization of reference_­wrapper.
move_only_function& operator=(move_only_function&& f);
Effects: Equivalent to: move_­only_­function(std​::​move(f)).swap(*this);
Returns: *this.
move_only_function& operator=(nullptr_t) noexcept;
Effects: Destroys the target object of *this, if any.
Returns: *this.
template<class F> move_only_function& operator=(F&& f);
Effects: Equivalent to: move_­only_­function(std​::​forward<F>(f)).swap(*this);
Returns: *this.
~move_only_function();
Effects: Destroys the target object of *this, if any.

20.14.17.4.4 Invocation [func.wrap.move.inv]

explicit operator bool() const noexcept;
Returns: true if *this has a target object, otherwise false.
R operator()(ArgTypes... args) cv ref noexcept(noex);
Preconditions: *this has a target object.
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 and F is the type of f.

20.14.17.4.5 Utility [func.wrap.move.util]

void swap(move_only_function& other) noexcept;
Effects: Exchanges the target objects of *this and other.
friend void swap(move_only_function& f1, move_only_function& f2) noexcept;
Effects: Equivalent to f1.swap(f2).
friend bool operator==(const move_only_function& f, nullptr_t) noexcept;
Returns: true if f has no target object, otherwise false.