The basis from my question I took from here: Failure to deduce template argument std::function from lambda function The question in this thread is: Why this code can't pass the lambda to the function:
#include <iostream>
#include <functional>
template <typename T>
void call(std::function<void(T)> f, T v)
{
f(v);
}
int main(int argc, char const *argv[])
{
auto foo = [](int i) {
std::cout << i << std::endl;
};
call(foo, 1);
return 0;
}
The answer in this thread is, since a lambda isn't a std::function
. But why is this code compiling:
#include <iostream>
#include <functional>
template <typename T>
void call(std::function<void(T)> f, T v)
{
f(v);
}
int main(int argc, char const *argv[])
{
auto foo = [](int i) {
std::cout << i << std::endl;
};
call({foo}, 1); // changed foo to {foo}
return 0;
}
A lambda that contains move-only variables is only accepted by the following variants: template <typename F> void use_func(F& func) template <typename F> void use_func(F&& func)
Passing Lambda Expressions as Arguments You can pass lambda expressions as arguments to a function. If you have to pass a lambda expression as a parameter, the parameter type should be able to hold it. If you pass an integer as an argument to a function, you must have an int or Integer parameter.
The std::invoke() method can be used to call functions, function pointers, and member pointers with the same syntax: #include <iostream>#include <functional>using namespace std;void globalFunction( ) { cout << "globalFunction ..." <<
One of the new features introduced in Modern C++ starting from C++11 is Lambda Expression. It is a convenient way to define an anonymous function object or functor. It is convenient because we can define it locally where we want to call it or pass it to a function as an argument.
As written in the linked answer, the first version does not compile, because template argument deduction fails for the first argument; a lambda is never an std::function<void(T)>
.
The second version compiles, because, by writing {foo}
, std::function<void(T)>
becomes a non-deduced context. So deduction can no longer fail for the first argument, as it isn't even attempted. So T
is deduced as int
solely from the second argument, and the call succeeds, because the lambda is convertible to an std::function<void(int)>
.
From [temp.deduct.type]:
The non-deduced contexts are:
- ...
- A function parameter for which the associated argument is an initializer list but the parameter does not have a type for which deduction from an initializer list is specified.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With