试图保持一个对象存活(但不需要引用shared_ptr这样做)我发现自己写的东西是这样的:
void ClassDerivedFromSharedFromThis::countdown(ThreadPool &pool, std::string name){
auto self = shared_from_this();
pool.then([=, self]{
for(int i = 0;i < 10;++i){
atomic_cout() << "Hey [" << name << "]! Our counter is: " << atomicCounter++ << "\n";
}
});
}
但后来视觉工作室出现错误,说我无法明确地复制捕获因为我已经隐式地进行了复制捕获......这迫使我写道:
void countdown(ThreadPool &pool, std::string name){
auto self = shared_from_this();
pool.then([=]{
self; //Capture self.
for(int i = 0;i < 10;++i){
atomic_cout() << "Hey [" << name << "]! Our counter is: " << atomicCounter++ << "\n";
}
});
}
我知道这有效,但感觉不对。由于我只需要shared_ptr所有权的副作用而不需要直接引用它,我想在捕获列表而不是lambda体中表达它。
在我的真实代码中,我想要在网络代码中的几个嵌套lambda中捕获大约5或6个变量,并且隐式捕获更好更容易编辑。
我的问题是:这是标准行为还是Visual Studio 2015对lambda捕获限制的看法?该标准的较新版本是否允许这样做,或者是否有人谈过它?
答案 0 :(得分:7)
是的,这是标准行为。来自C ++ 14(N4140)[expr.prim.lambda] / 8
如果 lambda-capture 包含 capture-default
=
,那个 simple-capture > lambda-capture 的格式应为“&amp;标识符”。
因此,如果你有[=]
,那么你所做的任何其他捕获都必须通过像
[=, &some_var]{} // copy all implicitly but explicitly capture some_var by reference
规则确实在C ++ 17中有所改变,但它是允许的
[=, *this]{};
将把对象的副本捕获到lambda中。
答案 1 :(得分:1)
您可以使用init-capture:
执行所需操作void ClassDerivedFromSharedFromThis::countdown(ThreadPool &pool, std::string name){
pool.then([=, self=shared_from_this()]{
for(int i = 0;i < 10;++i){
atomic_cout() << "Hey [" << name << "]! Our counter is: " << atomicCounter++ << "\n";
}
});
}
使用奖金,您无需单独声明self
。