23 General utilities library [utilities]

23.14 Function objects [function.objects]

23.14.13 Polymorphic function wrappers [func.wrap]

This subclause describes a polymorphic wrapper class that encapsulates arbitrary callable objects.

23.14.13.1 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:
    // [func.wrap.badcall.const], constructor
    bad_function_call() noexcept;
  };
}

23.14.13.1.1 bad_­function_­call constructor [func.wrap.badcall.const]

bad_function_call() noexcept;
Effects: Constructs a bad_­function_­call object.
Postconditions: what() returns an implementation-defined ntbs.

23.14.13.2 Class template function [func.wrap.func]

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&&);
    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>;

  // [func.wrap.func.nullptr], Null pointer comparisons
  template <class R, class... ArgTypes>
    bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept;

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

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

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

  // [func.wrap.func.alg], specialized algorithms
  template <class R, class... ArgTypes>
    void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&) noexcept;
}
The function class template provides polymorphic wrappers that generalize the notion of a function pointer.
Wrappers can store, copy, and call arbitrary callable objects ([func.def]), given a call signature ([func.def]), allowing functions to be first-class objects.
A callable type ([func.def]) 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 (Clause [expr]), is well formed ([func.require]).
The function class template is a call wrapper ([func.def]) whose call signature ([func.def]) is R(ArgTypes...).
[ Note
:
The types deduced by the deduction guides for function may change in future versions of this International Standard.
— end note
 ]

23.14.13.2.1 function construct/copy/destroy [func.wrap.func.con]

function() noexcept;
Postconditions: !*this.
function(nullptr_t) noexcept;
Postconditions: !*this.
function(const function& f);
Postconditions: !*this if !f; otherwise, *this targets a copy of f.target().
Throws: shall not throw exceptions 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.
[ Note
:
Implementations are encouraged to 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.
— end note
 ]
function(function&& f);
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.
Throws: shall not throw exceptions 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 or move constructor of the stored callable object.
[ Note
:
Implementations are encouraged to 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.
— end note
 ]
template<class F> function(F f);
Requires: F shall be CopyConstructible.
Remarks: This constructor template shall not participate in overload resolution unless F is Lvalue-Callable ([func.wrap.func]) for argument types ArgTypes... and return type R.
Postconditions: !*this if any of the following hold:
  • f is a null function pointer value.
  • f is a null member pointer value.
  • F is an instance of the function class template, and !f.
Otherwise, *this targets a copy of f initialized with std​::​move(f).
[ Note
:
Implementations are encouraged to avoid the use of dynamically allocated memory for small callable objects, for example, where f is an object holding only a pointer or reference to an object and a member function pointer.
— end note
 ]
Throws: shall not throw exceptions when f is a function pointer or a reference_­wrapper<T> for some T.
Otherwise, may throw bad_­alloc or any exception thrown by F's copy or move constructor.
template<class F> function(F) -> function<see below>;
Remarks: This deduction guide participates in overload resolution only if &F​::​operator() is well-formed when treated as an unevaluated operand.
In that case, if decltype(&F​::​operator()) is of the form R(G​::​*)(A...) cv & noexcept for a class type G, then the deduced type is function<R(A...)>.
[ Example
:
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);
Effects: As if by: function(std​::​forward<F>(f)).swap(*this);
Returns: *this.
Remarks: This assignment operator shall not participate in overload resolution unless decay_­t<F> is Lvalue-Callable ([func.wrap.func]) for argument types ArgTypes... and return type R.
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.

23.14.13.2.2 function modifiers [func.wrap.func.mod]

void swap(function& other) noexcept;
Effects: interchanges the targets of *this and other.

23.14.13.2.3 function capacity [func.wrap.func.cap]

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

23.14.13.2.4 function 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 wrapped callable object.

23.14.13.2.5 function 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.

23.14.13.2.6 null pointer comparison functions [func.wrap.func.nullptr]

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

23.14.13.2.7 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);