无法捕获lambda [duplicate]中的静态变量

问题描述 投票:4回答:2

这似乎很奇怪,我可以捕获静态变量,但是仅当捕获列表中未指定该变量时,即隐式捕获它。

int main()
{
    int captureMe = 0;
    static int captureMe_static = 0;

    auto lambda1 = [&]() { captureMe++; };  // Works, deduced capture
    auto lambda2 = [&captureMe]() { captureMe++; }; // Works, explicit capture
    auto lambda3 = [&] () { captureMe_static++; };  // Works, capturing static int implicitly
    auto lambda4 = [&captureMe_static] { captureMe_static++; }; // Capturing static in explicitly:  
                                                                // Error: A variable with static storage duration 
                                                                // cannot be captured in a lambda

    // Also says "identifier in capture must be a variable with automatic storage duration declared
    // in the reaching scope of the lambda

    lambda1(); lambda2(); lambda3();    // All work fine

    return 0;
}

我不明白,第三和第四张照片应该是相同的,不是吗?在第三部分中,我没有使用“自动存储期限”捕获变量。

编辑:我认为答案是它永远不会捕获静态变量,所以:

auto lambda = [&] { captureMe_static++; };   // Ampersand says to capture any variables, but it doesn't need to capture anything so the ampersand is not doing anything
auto lambda = [] { captureMe_static++; };  // As shown by this, the static doesn't need to be captured, and can't be captured according to the rules.
c++ lambda static capture
2个回答
7
投票

具有静态存储持续时间的变量不需要捕获,因此无法捕获。您可以在lambda中简单地使用它。

对于自动变量,存在一个问题:虽然在其他语言中,闭包将仅在封闭范围内存储对变量的引用,但在C ++中,lambda无法延长自动变量的生存期,因此可能超出范围,在lambda中留下一个悬挂的引用。因此,C ++允许您选择是通过复制还是通过引用捕获自动变量。但是,如果变量是静态的,则不会出现此问题。该lambda的行为就好像它已被引用捕获一样。

如果您确实想通过value捕获静态变量,请使用C ++ 14 init-capture语法。


0
投票

这不是您想要的吗?

static int dont_capture_me = 0;

auto foo = [] { dont_capture_me++; };

当然,您可以显式存储引用,但是它们本质上是等效的。

auto bar = [&reference = dont_capture_me] { reference++; };
© www.soinside.com 2019 - 2024. All rights reserved.