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 looks like:
[ capture_list ]( argument_list )
-> return_type optional_mutable
{
code
}
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(); }
1 In addition, RTTI is stored (typeid), and the cast-back-to-original-type operation is included.