Is it possible to define a lambda in C++ with default generic argument?
int main(){
auto lambda = [](auto i = 0){return i;};
std::cout<<lambda()<<"\n"; // this does not compile
std::cout<<lambda(4)<<"\n"; // this does compile
auto lambda2 = [](int i = 0){return i;};
std::cout<<lambda2()<<"\n"; // this is also OK
}
I wonder if it's possible to reproduce something like this functor, and why not
struct Lambda{
template<typename T=int>
auto operator()(T i=1){ return i;}
};
A lambda expression can't specify type parameters, so it's not generic. However, a functional interface associated with lambda expression is generic. In this case, the target type of lambda expression has determined by the type of argument(s) specified when a functional interface reference is declared.
Significance of Lambda Function in C/C++ Lambda Function − Lambda are functions is an inline function that doesn't require any implementation outside the scope of the main program. Lambda Functions can also be used as a value by the variable to store.
You can use as many arguments as you want in a lambda function, but it can have only one expression. This expression is evaluated and returned as a result.
Just like a normal function, a Lambda function can have multiple arguments with one expression. In Python, lambda expressions (or lambda forms) are utilized to construct anonymous functions. To do so, you will use the lambda keyword (just as you use def to define normal functions).
You can do that with a wrapper:
template<class F, class DefaultArg>
struct DefaultArgWrapper
{
F f;
DefaultArg default_arg;
template<class... Args>
decltype(auto) operator()(Args&&... args) {
return f(std::forward<Args>(args)...);
}
decltype(auto) operator()() {
return f(default_arg);
}
};
template<class F, class DefaultArg>
DefaultArgWrapper<F, DefaultArg> with_default_arg(F&& f, DefaultArg arg) {
return {std::move(f), std::move(arg)};
}
int main(){
auto lambda = with_default_arg([](auto i){return i;}, 0);
std::cout<<lambda()<<"\n";
std::cout<<lambda(4)<<"\n";
}
An alternative C++17 solution:
template<class... F>
struct ComposeF : F... {
template<class... F2>
ComposeF(F2&&... fs)
: F(std::forward<F2>(fs))...
{}
using F::operator()...;
};
template<class... F>
ComposeF<std::decay_t<F>...> composef(F&&... fs) {
return {std::forward<F>(fs)...};
}
int main() {
auto lambda = [](auto i) { return i; };
auto f = composef(lambda, [&lambda](int i = 0) { return lambda(i); });
std::cout << f() << '\n';
std::cout << f(1) << '\n';
}
A bit sub-optimal though, since there are two copies of lambda
involved: one copy in ComposeF
, another is the original lambda
on the stack. If lambda
is mutable that would be an issue.
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