是否可以访问(只读)lambda捕获的变量?
这不起作用:
os.environ['https_proxy']="https://iss-uk.corporate.pb.com:80"
p =sp.Popen(["curl","-i","-X", "POST" ,"-H", "Content-Type:application/json" ,"-H", "Authorization:Basic NEg0VU9QR1BZODAWVI4N1dLUFpXRzp4WG1HczbUFuVG9RUlJDcXBLWkdB","-d", '{ "grant_type": "client_credentials" }', "https://rridata.wikimapia.com/v1.0/oauth/token/"], stdout = sp.PIPE, shell=False)
#p =sp.check_output(['curl','-i','-X', 'POST' ,'-H', 'Content-Type:application/json' ,'-H', 'Authorization:Basic NEg0VU9QR1BZODATEpDc2oyNGRGa0c5SVpxUUkzbUFuVG9RUlJDcXBLWkdB','-d', '{ "grant_type": "client_credentials" }', 'https://rdata.wikimapia.com/v1.0/oauth/token/'])
out,err = p.communicate()
print ("out:",out,"err:",err)
答案 0 :(得分:16)
auto plus( double a ) {
using R = struct {
double a;
double operator()(double b)const{return b+a;}
};
return R{std::move(a)};
}
请注意,std::function
不是lambda,lambda不是std::function
。他们互相合作,但使用一个术语来引用另一个术语则是有用的。
答案 1 :(得分:14)
这不是如何使用lambda。
lambda的接口是它的函数签名。其捕获应被视为实现细节,并且对用户不可见。
如果要显式访问捕获,请编写自己的函数对象并相应地公开相应的数据成员:
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;
答案 2 :(得分:9)
“绝对没有将它存储在std函数中。没有它,我可以用C ++中的一个可怕的(但合法的)黑客攻击17。但是我会是一个可怕的人告诉你如何,因为你可能用它。” - Yakk
好吧,让我们减轻Yakk的业力;这里是C ++ 14解决方案的概念证明,你绝对不想放弃它:
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
可以使用任意数量的仿函数并将它们合并为一个仿函数。我从this blog post借用了这个想法,并在评论部分的帮助下使其真正起作用。
生成的仿函数用于在cap<N>
标记和函数的实际参数之间进行标记分派。因此,调用magic(cap<0>)
会导致它吐出相应的捕获变量,即a
。当然,通过正常调用magic(123)
可以访问函数的实际行为。
作为奖励,外部lambda为mutable
,捕获访问器通过引用返回:您实际上对捕获的变量具有读写权限!
您可以在Coliru right here的自然栖息地观察并与此生物互动。