In C++14, generalized lambda capture let us do:
template<class T>
auto pack(T t)
{
return [t=std::move(t)](auto&& f){f(t);};
};
But it doesn't play with param-pack:
template<class... T>
auto pack(T... t)
{
return [t=std::move(t)...](auto&& f){f(t...);};
};
Is there any special syntax or further standard proposal to address this?
The lambda is capturing an outside variable. A lambda is a syntax for creating a class. Capturing a variable means that variable is passed to the constructor for that class. A lambda can specify whether it's passed by reference or by value.
Permalink. All the alternatives to passing a lambda by value actually capture a lambda's address, be it by const l-value reference, by non-const l-value reference, by universal reference, or by pointer.
Lambdas always capture objects, and they can do so by value or by reference.
C++11 introduces lambdas allow you to write an inline, anonymous functor to replace the struct f . For small simple examples this can be cleaner to read (it keeps everything in one place) and potentially simpler to maintain, for example in the simplest form: void func3(std::vector<int>& v) { std::for_each(v.
My draft of C++14 says ([expr.prim.lambda]/24):
A simple-capture followed by an ellipsis is a pack expansion (14.5.3). An init-capture followed by an ellipsis is ill-formed.
So it looks like there is no way to do a variadic generalized capture. A possible workaround is to just capture the arguments in a tuple and then use one of the solutions suggested here: "unpacking" a tuple to call a matching function pointer
auto pack(T... t)
{
return [args=make_tuple(std::move(t)...)](auto&& f){
// find a way to call f with args
};
};
EDIT:
It's now voted into C++20, made by this proposal. Although the syntax is a bit different:
template<class... T>
auto pack(T... t)
{
return [...t=std::move(t)](auto&& f){f(t...);};
};
Note that the ...
is before the init-capture.
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