有没有办法从外部更改lambda中通过复制捕获的变量?
示例:
#include <iostream>
int main() {
int x = 3;
auto f = [x]() { std::cout << x << std::endl; };
// is there anything I can do here to make f print 4?
f();
}
如果可以的话,感觉真的很脏。有没有令人信服的理由我为什么不考虑这样做呢?
答案 0 :(得分:1)
#include <iostream>
int main()
{
int x = 3;
auto f = [&x]() { std::cout << x << std::endl; };
x++;
f();
}
答案 1 :(得分:1)
要回答你的问题,不能从外面改变函数/函子的局部变量(这是lambda的局部变量)。
将lambda视为“常规”函数,其名称是您没有的。就像常规函数一样,你不能从外部改变局部变量值(通过值传递的参数),你也不能用lambda来做。这是安全性和安全性的必要条件。结果的可预测性。
如果您遇到需要执行此操作的问题,则其他人建议使用[&]
语法。
(存在https://www.eecs.umich.edu/courses/eecs588.w14/static/stack_smashing.pdf,但我认为这依赖于编译器/系统实现的知识,并且通常会进入未定义的行为)
答案 2 :(得分:0)
struct do_nothing{ template<class...Args> void operator()(Args&&...)const{}};
template<class...cmd>
struct maybe_run_t;
template<> struct maybe_run_t<>:do_nothing{};
template<class cmd>struct maybe_run_t<cmd>{
cmd&& value;
template<class...Args>
void operator()(Args&&...args)const{
value(std::forward<Args>(args)...);
}
};
template<class...Args>
maybe_run_t<Args...> maybe_run(Args&&...args){
return {std::forward<Args>(args)...};
}
然后:
int x = 3;
auto f = [x](auto&&...cmd)mutable { maybe_run(cmd...)(x); std::cout << x << std::endl; };
// is there anything I can do here to make f print 4?
f([](auto&x){x=4;});
f();
打印4\n4\n
。
您有一个可选参数。如果您传递一个,则会修改x
。如果不这样做,代码就可以运行。
您还可以根据其存在或返回值进行流量控制。
答案 3 :(得分:0)
恢复原始的“lambda”类型:使用operator()
创建结构或类struct myLambda
{
int x;
myLambda(int x) : x(x) {};
operator() { std::cout << x << '\n'; }
};
答案 4 :(得分:0)
在C ++ 14中,您可以这样做:
#include<iostream>
int main() {
int x = 0;
auto l = [x]()mutable->decltype(auto){
std::cout << x << std::endl;
return (x);
};
l() = 42;
l();
}
实际上,在C ++ 11中也很容易做类似的事情:
auto l = [x]()mutable->decltype(x)&{
std::cout << x << std::endl;
return x;
};
也就是说,您可以通过引用返回来修改由副本捕获的变量。