A lambda is not a std::function
, and std::function
is not a lambda.
A lambda is syntactic sugar to create an anonymous class that looks like this:
struct my_lambda {
private:
int captured_int;
double captured_double;
char& referenced_char;
public:
int operator()( float passed_float ) const {
// code
}
};
int captured_int = 7;
double captured_double = 3.14;
char referenced_char = 'a';
my_lambda closure {captured_int, captured_double, referenced_char};
closure( 2.7f );
from this:
int captured_int = 7;
double captured_double = 3.14;
char referenced_char = 'a';
auto closure = [=,&referenced_char](float passed_float)->int {
// code
};
closure(2.7);
with the type name of the my_lambda
actually being some unnameable type.
A std::function
is a completely different thing. It is an object that does implement operator()
with a particular signature, and stores a smart value-semantics pointer to an abstract interface that covers copy/move/invoke operations. It has a template
d constructor that can take any type that supports copy/move/operator()
with a compatible signature, generates a concrete custom class that implement the abstract internal interface, and stores it in the above mentioned internal value-semantics smart pointer.
It then forwards operations from itself as a value-type to the abstract internal pointer, including perfect forwarding to the invocation method.
As it happens, you can store a lambda in a std::function
, just like you can store a function pointer.
But there are a whole myriad of different std::function
that could store a given lambda -- anything where the types are convertible to and from the arguments works, and in fact works equally well, as far as the std::function
is concerned.
Type deduction in C++ in template
s does not work at the level "can you convert into" -- it is pattern matching, pure and simple. As the lambda is a type unrelated to any std::function
, no std::function
type can be deduced from it.
If C++ tried to do that in the general case, it would have to invert a Turing-complete process to determine what (if any) set of types could be passed to the template
in order to generate a conversion-compatible instance.
In theory, we could add "operator deduce template arguments from" to the language, where the implementers of a given template
can write code that takes some arbitrary type, and they attempt to tease out "from this type, what template
parameters should be used for an instance". But C++ does not have this.