Functional

This header is part of the function objects library and provides the standard hash function.

std::function

template< class >
class function;

template< class R, class... Args>
class function<R(Args...)>

Class template std::function is a general-purpose polymorphic(多态性) function wrapper. Instances of std::function can store, copy, an invoke and CopyConstructile Callable target – functions (via pointers thereto), lambda expressions, bind expressions, or other function objects, as well as pointers to member functions and pointers to data members.

The stored callable object is called the target of std::function. If a std::function contains no target, it is called empty. Invoking the target of an empty. Invoking the target of an empty std::function results in std::bad_function_call exception being thrown. std::function satisfies the requirements of CopyConstructible and CopyAssignable.

  • Member types
Type Definition
result_type R
argument_type T if sizeof...(Args) == 1 and T is the first and only type in Args…
first_argument_type T if sizeof...(Args) == 2 and T is the first of the two types in Args…
second_argument_type T if sizeof...(Args) == 2 and T is the second of the two types in Args…
  • Member functions
(constructor) constructs a new std::function instance
(destructor) destorys a std::function instance
operator= assigns a new target
swap swaps the contents
assign (removed in c++17) assigns a new target
operator bool checks if a tagrt is contained
operator() invokes the target
target_type obtains the typeid of the stored target
target obtains a pointer to the stored target
  • Non-member functions
std::swap (c++11) specializes the std::swap algorithm
operator== / operator!=(removed in c++20) compares a std::function with nullptr
  • Helper classes
std::uses_allocator (c++11)(until c++17) specializes the std::uses_allocator type trait
  • Deduction guides

Care should be taken when a std::function, whose result type is a reference, is initialized from a lambda expression without a trailing-return-type. Due to the way auto deduction works, such lambda expression will always return a prvalue. Hence, the resulting reference will usually bind to a temporary whose lifetime ends when std::function::operator() returns. (until c++23)

If a std::function returning a reference is initialized from a function or function object returning a prvalue (including a lambda expression without a trailing-return-type), the program is ill-formed because binding the returned reference to a temporary object is forbidden. (since c++23)

std::function<const int&()> F([] { return 42; }); // Error ince C++23: can't bind the returned reference to a temporary

int x = F(); // Undefined behavior until c++23: the result of F() is a dangling referece

std::function<int&()> G([]() => int& { static int i{0x2A}; return i; }); // OK

std::function<const int&()> H([i{052}] -> const int& { return i; }); // OK
  • Example
#include <functional>
#include <iostream>

struct Foo {
  Foo(int num) : num_(num) {}
  void print_add(int i) const { std::cout << num_ + i << '\n'; }
  int num_;
};

void print_num(int i) { std::cout << i << "\n"; };

struct PrintNum {
  void operator()(int i) const { std::cout << i << "\n"; }
};

int main() {
  // store a free function
  std::function<void(int)> f_display = print_num;
  f_display(-9);

  // store a lambda
  std::function<void()> f_display_42 = []() { print_num(42); };
  f_display_42();

  // store the result of a call to std::bind
  std::function<void()> f_display_31337 = std::bind(print_num, 31337);
  f_display_31337();

  // store a call to a member function
  std::function<void(const Foo &, int)> f_add_display = &Foo::print_add;
  const Foo foo(314159);
  f_add_display(foo, 1);
  f_add_display(314159, 1);

  // store a call to a data member accessor
  std::function<int(Foo const &)> f_num = &Foo::num_;
  std::cout << "num_: " << f_num(foo) << "\n";

  // store a call to member function and object
  using std::placeholders::_1;
  std::function<void(int)> f_add_display3 =
      std::bind(&Foo::print_add, &foo, _1);
  f_add_display3(3);

  // store a call to a function object
  std::function<void(int)> f_display_obj = PrintNum();
  f_display_obj(18);

  auto factorial = [](int n) {
    // store a lambda object to emulate "recursive lambda"; aware of extra
    // overhead
    std::function<int(int)> fac = [&](int n) {
      return (n < 2) ? 1 : n * fac(n - 1);
    };
    // note that "auto fac = [&](int n) {...}" does not work in recursive
    // calls
    return fac(n);
  };

  for (int i{5}; i != 8; ++i) {
    std::cout << i << "! = " << factorial(i) << ";  ";
  }
  std::cout << "\n";
}