我是cpp的新手并尝试使用lambda函数.我有一个计数器,我试图在lambda函数内部和它之外增加.我看到一些奇怪的记忆错误,我无法理解.这是我正在使用这个计数器的流程.有什么我做错了.
bool SomeClass::func() {
int64_t counter = 0;
//some loop logic {
counter++;
}
auto lamb = [this, &counter]() {
//some logic
counter++;
}
someotherFunction(data, lamb); // this function will execute the lambda
}
Run Code Online (Sandbox Code Playgroud)
问题是C++ lambdas无法解决" 向上funarg "的情况,即当一个局部变量被一个lambda引用捕获时,它继承了本地的"所有者"(因为它存储在某个地方或因为它作为函数返回结果).
当lambda通过引用捕获变量时,C++所做的只是将引用变量的地址存储在lambda代码使用的上下文结构中.
然而,在您的情况下,变量本身是一个局部的,并且位于创建lambda的堆栈框架中.如果在执行期间刚刚调用了lambda对象,someOtherFunction那么事情很好,但是如果lambda被存储起来并且在创建它的堆栈帧中幸存(或者更精确地创建了lambda中引用的捕获变量),它的执行将引用一个不再存在的变量(未定义的行为).
在一般情况下解决"向上funarg"问题需要垃圾收集器,而C++没有垃圾收集器.
在某些情况下你可以做的是捕获"按值",因此lambda将拥有自己的私有副本:
foo([counter]() mutable { counter++; })
Run Code Online (Sandbox Code Playgroud)
在这种情况下,如果你想要更改捕获的副本,你还需要使用mutable关键字,因为......好吧,因为如果你想修改捕获的副本,这就是C++所需要的(捕获的副本是否const是主体中的对象) lambda).
不幸的是,如果您需要共享捕获的变量,例如使用两个lambdas(例如,在同一个捕获的变量上创建"增量器"和"减量器"),则使用副本是不可行的.您可以为此做的是通过值a捕获std::shared_ptr变量,这将正确地替换垃圾收集器以用于简单情况(但不是在引用循环的情况下).
| 归档时间: |
|
| 查看次数: |
176 次 |
| 最近记录: |