返回捕获局部变量的lambda [英] Returning a lambda capturing a local variable

查看:134
本文介绍了返回捕获局部变量的lambda的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天,我在C ++ 11 lambda中遇到了一种非常不直观的行为(至少对我而言)。有问题的代码如下:

Today I encountered a very unintuitive behavior (for me, at least) in C++11 lambdas. The code in question is the following:

#include <stdio.h>

auto sum(int x) {
    return [&x](int y) {
        return x + y;
    };
}

int main() {
    int a = sum(2)(3);
    printf("%d\n",a);
}

而不是打印5,而是打印出乱码。实际上,至少在我的GCC版本中,如果打开-O2优化标志,它实际上会打印5。由于输出取决于编译器的优化级别,因此它是未定义的行为。过一会儿,我想我了解发生了什么。

Instead of printing 5, this prints gibberish. Actually, at least in my version of GCC, if I turn on the -O2 optimization flag, it actually prints 5. Since the output depends on the optimization level of the compiler, it is undefined behavior. After a while, I think I understood what is happening.

调用函数sum时,将与参数x对应的堆栈变量设置为2,然后该函数sum返回,并且此堆栈变量可能会被编译器执行以下代码所需放置的所有内容覆盖,并且在最终执行lambda时,x不再保留2的位置,程序将3加到

When the function sum is called, a stack variable corresponding to the argument x is set to 2, then the function sum returns, and this stack variable might be overwritten by anything that the compiler needs to put there to execute following code, and by the time the lambda eventually gets executed, the place where x was no longer holds 2, and the program adds 3 to an arbitrary integer.

在C ++中,有什么优雅的方法可以确保正确捕获变量吗?

Is there any elegant way to do currying in C++ guaranteeing that the variable gets captured correctly?

推荐答案

int x 的生存期有限。对自动存储变量(称为堆栈)的引用仅在变量的生命周期内有效。在这种情况下,仅直到变量存在的堆栈框架(范围)或函数参数的函数的末尾为止。

int x has a limited lifetime. References to automatic storage variables (what you call "the stack") are only valid over the variable's lifetime. In this case, only until the end of the stack frame (the scope) where the variable exists, or the function for function arguments.

[ &] 通过引用捕获任何提及的(本地)变量,但 this (如果使用或隐式使用,则按值捕获)除外。 [=] 按值捕获任何提及的变量。 [x] 会明确捕获 x ,而 [& x] 通过显式引用。在C ++ 17中, [* this] 也可以。

[&] captures any mentioned ("local") variable by reference, except this (which is captured by value if used or implicitly used). [=] captures any mentioned variable by value. [x] would capture x explicitly, and [&x] by reference explicitly. In C++17, [*this] also works.

还有 [x = std :: move(x)] [blah = expression]

通常,如果lambda的寿命将超过当前范围,请不要使用 [&] :明确说明捕获的内容。

In general, if the lambda will outlive the current scope don't use [&]: be explicit about what you capture.

这篇关于返回捕获局部变量的lambda的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆