Is it possible to access (read only) the variables captured by a lambda?
This doesn't work:
Please note that a
2.
Well let's relieve Yakk's karma; here's a proof of concept of a C++14 solution which you definitely don't want to let loose in the wild:
The resulting functor is used to tag-dispatch between the
As a bonus, the outer lambda is
You can observe and interact with this creature in its natural habitat on Coliru right here.
This doesn't work:
std::function<double (const double)> plus (const double a) {
return [a] (const double b) -> double {
return a+b;
};
}
auto plus5 = plus(5);
cout << plus5.a << endl;
----Answers------
1.
auto plus( double a ) {
using R = struct {
double a;
double operator()(double b)const{return b+a;}
};
return R{a};
}
live example.Please note that a
std::function
is not a lambda, and lambda is not a std::function
. They work with each other, but using one term to refer to the other is the opposite of helpful.2.
This is not how a lambda should be used.
The interface of a lambda is its function signature. Its captures should be considered an implementation detail and not be visible to the user.
If you want explicit access to the captures, write your own function object and expose the respective data members accordingly:
3. The interface of a lambda is its function signature. Its captures should be considered an implementation detail and not be visible to the user.
If you want explicit access to the captures, write your own function object and expose the respective data members accordingly:
struct MyPlus {
double a;
MyPlus(double x) : a(x) {}
double operator()(const double b)
{
return a+b;
}
};
auto plus5 = MyPlus(5);
std::cout << plus5.a;
Well let's relieve Yakk's karma; here's a proof of concept of a C++14 solution which you definitely don't want to let loose in the wild:
auto magic = [a, b](auto &&... args) mutable -> decltype(auto) {
return makeOverload(
// Capture access boilerplate
[&](cap_<0>) -> auto& { return a; },
[&](cap_<1>) -> auto& { return b; },
// Actual function
[&](int p) {
return "[" + std::to_string(a) + ", " + b + "](" + std::to_string(p) + ")";
}
)(std::forward<decltype(args)>(args)...);
};
makeOverload
takes any number of functors and blends them into a single one. I borrowed the idea from this blog post, with help from the comment section to make it actually work.The resulting functor is used to tag-dispatch between the
cap<N>
tags and the actual parameters of the function. Thus, calling magic(cap<0>)
causes it to spit out the corresponding captured variable, that is a
. The actual behaviour of the function is, of course, still accessible with a normal call to magic(123)
.As a bonus, the outer lambda is
mutable
, and the capture accessors return by reference: you actually have read-write access to the captured variables!You can observe and interact with this creature in its natural habitat on Coliru right here.
0 nhận xét:
Post a Comment