This subclause describes a polymorphic wrapper class that encapsulates arbitrary callable objects.
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 std::exception { public: // [func.wrap.badcall.const], constructor: bad_function_call() noexcept; }; } // namespace std
Effects: constructs a bad_function_call object.
namespace std { template<class> class function; // undefined template<class R, class... ArgTypes> class function<R(ArgTypes...)> { public: typedef R result_type; typedef T1 argument_type; // iff sizeof...(ArgTypes) == 1 and // the type in ArgTypes is T1 typedef T1 first_argument_type; // iff sizeof...(ArgTypes) == 2 and // ArgTypes contains T1 and T2 typedef T2 second_argument_type; // iff sizeof...(ArgTypes) == 2 and // ArgTypes contains T1 and T2 // [func.wrap.func.con], construct/copy/destroy: function() noexcept; function(nullptr_t) noexcept; function(const function&); function(function&&); template<class F> function(F); template<class A> function(allocator_arg_t, const A&) noexcept; template<class A> function(allocator_arg_t, const A&, nullptr_t) noexcept; template<class A> function(allocator_arg_t, const A&, const function&); template<class A> function(allocator_arg_t, const A&, function&&); template<class F, class A> function(allocator_arg_t, const A&, F); function& operator=(const function&); function& operator=(function&&); function& operator=(nullptr_t); 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; template<class F, class A> void assign(F&&, const A&); // [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 std::type_info& target_type() const noexcept; template <typename T> T* target() noexcept; template <typename T> const T* target() const noexcept; }; // [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...)>&); template<class R, class... ArgTypes, class Alloc> struct uses_allocator<function<R(ArgTypes...)>, Alloc> : true_type { }; }
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 object f of type F is Callable for argument types ArgTypes and return type R if the expression INVOKE(f, declval<ArgTypes>()..., R), 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...).
When any function constructor that takes a first argument of type allocator_arg_t is invoked, the second argument shall have a type that conforms to the requirements for Allocator (Table [allocator.requirements]). A copy of the allocator argument is used to allocate memory, if necessary, for the internal data structures of the constructed function object.
function() noexcept;
template <class A> function(allocator_arg_t, const A& a) noexcept;
Postconditions: !*this.
function(nullptr_t) noexcept;
template <class A> function(allocator_arg_t, const A& a, nullptr_t) noexcept;
Postconditions: !*this.
function(const function& f);
template <class A> function(allocator_arg_t, const A& a, 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 callable object passed via 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);
template <class A> function(allocator_arg_t, const A& a, function&& f);
Effects: If !f, *this has no target; otherwise, move-constructs the target of f into the target of *this, leaving f in a valid state with an unspecified value.
template<class F> function(F f);
template <class F, class A> function(allocator_arg_t, const A& a, F f);
Requires: F shall be CopyConstructible. f shall be Callable ([func.wrap.func]) for argument types ArgTypes and return type R. The copy constructor and destructor of A shall not throw exceptions.
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's target 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.
function& operator=(const function& f);
Effects: 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);
Effects: If *this != NULL, destroys the target of this.
Postconditions: !(*this).
Returns: *this
template<class F> function& operator=(F&& f);
Effects: function(std::forward<F>(f)).swap(*this);
Returns: *this
template<class F> function& operator=(reference_wrapper<F> f) noexcept;
Effects: function(f).swap(*this);
Returns: *this
Effects: If *this != NULL, destroys the target of this.
void swap(function& other) noexcept;
Effects: interchanges the targets of *this and other.
template<class F, class A>
void assign(F&& f, const A& a);
Effects: function(allocator_arg, a, std::forward<F>(f)).swap(*this)
explicit operator bool() const noexcept;
Returns: true if *this has a target, otherwise false.
R operator()(ArgTypes... args) const
Effects: INVOKE(f, std::forward<ArgTypes>(args)..., R) ([func.require]), where f is the target object ([func.def]) of *this.
Returns: Nothing if R is void, otherwise the return value of INVOKE(f, std::forward<ArgTypes>(args)..., R).
Throws: bad_function_call if !*this; otherwise, any exception thrown by the wrapped callable object.
const std::type_info& target_type() const noexcept;
Returns: If *this has a target of type T, typeid(T); otherwise, typeid(void).
template<typename T> T* target() noexcept;
template<typename T> const T* target() const noexcept;
Requires: T shall be a type that is Callable ([func.wrap.func]) for parameter types ArgTypes and return type R.
Returns: If target_type() == typeid(T) a pointer to the stored function target; otherwise a null pointer.
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.
template<class R, class... ArgTypes>
void swap(function<R(ArgTypes...)>& f1, function<R(ArgTypes...)>& f2);
Effects: f1.swap(f2);