What is the purpose of std::function and how do I use it?

c++, c++11, function-pointers, lambda, std-function

Solution

`std::function` is a type erasure object. That means it erases the details of how some operations happen, and provides a uniform run time interface to them. For `std::function`, the primary1 operations are copy/move, destruction, and 'invocation' with `operator()` -- the 'function like call operator'.

In less abstruse English, it means that `std::function` can contain almost any object that acts like a function pointer in how you call it.

The signature it supports goes inside the angle brackets: `std::function<void()>` takes zero arguments and returns nothing. `std::function< double( int, int ) >` takes two `int` arguments and returns `double`. In general, `std::function` supports storing any function-like object whose arguments can be converted-from its argument list, and whose return value can be converted-to its return value.

It is important to know that `std::function` and lambdas are different, if compatible, beasts.

The next part of the line is a lambda. This is new syntax in C++11 to add the ability to write simple function-like objects -- objects that can be invoked with `()`. Such objects can be type erased and stored in a `std::function` at the cost of some run time overhead.

`[](){ code }` in particular is a really simple lambda. It corresponds to this:

struct some_anonymous_type {
  some_anonymous_type() {}
  void operator()const{
    code
  }
};

an instance of the above simple pseudo-function type. An actual class like the above is "invented" by the compiler, with an implementation defined unique name (often including symbols that no user-defined type can contain) (I do not know if it is possible that you can follow the standard without inventing such a class, but every compiler I know of actually creates the class).

The full lambda syntax (prior to c++20) looks like:

[ capture_list ]( argument_list )
-> return_type optional_mutable
{
  code
}

By c++23, the syntax expanded to:

[ capture_list ]
< template_params > requires_clauses
attributes ( argument_list )
-> return_type
{
  body
}

But many parts can be omitted or left empty. The capture_list corresponds to both the constructor of the resulting anonymous type and its member variables, the argument_list the arguments of the `operator()`, and the return type the return type. The constructor of the lambda instance is also magically called when the instance is created with the capture_list.

[ capture_list ]( argument_list ) -> return_type { code }

basically becomes

struct some_anonymous_type {
  // capture_list turned into member variables
  some_anonymous_type( /* capture_list turned into arguments */ ):
    /* member variables initialized */
  {}
  return_type operator()( argument_list ) const {
    code
  }
};

Note that in c++20 template arguments were added to lambdas, and that isn't covered above.

[]<typename T>( std::vector<T> const& v ) { return v.size(); }

and attributes c++20 and requires clauses c++23 also can be used with lambdas.

Template arguments after the `[]` apply to the `operator()` and not the lambda as a whole. Ie:

template<class T>
auto foo = [](T t) { return t+1; };

is a `template` variable, while

auto foo = []<class T>(T t) { return t+1; };

is a variable with a `template` `operator()`.

1 In addition, RTTI is stored (typeid), and the cast-back-to-original-type operation is included.

Problem

It is necessary for me to use `std::function` but I don't know what the following syntax means. ``` std::function<void()> f_name = []() { FNAME(); }; ``` What is the goal of using `std::function`? Is it to make a pointer to a function?

Original source