C++ lambda中的静态变量

Ove*_*erv 3 c++ lambda c++11

以下代码工作正常:

#include <iostream>
#include <functional>

std::function<int (void)> get_incrementer() {
    return []() {
        static int count = 0;
        return count++;
    };
}

int main() {
    using std::cout;

    auto incrementer = get_incrementer();

    cout << incrementer() << std::endl;
    cout << incrementer() << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是如果您通过引用捕获局部变量,它会突然导致未定义的行为,因为在调用时,堆栈上的位置正被其他东西使用.

std::function<int (void)> get_incrementer() {
    int count = 0;

    return [&count]() {
        return count++;
    };
}
Run Code Online (Sandbox Code Playgroud)

为什么编译器允许它呢?我希望编译器要么不允许这样做(检查这种情况似乎微不足道)或者改变局部变量的存储持续时间.

Nic*_*las 7

C++允许它,因为C++不是一种安全的语言.虽然这个案例可能是"微不足道"来检查(而且个人而言,我不同意它是微不足道的,但我不是编译器编写者),还有很多其他案例并不容易检查.

C++不是为您修复损坏的代码.它确实只是你告诉它的,即使它是非常不明智的.

此外,还不完全清楚你打算用这个代码做什么.例如,这些是完全不同的两件事:

std::function<int (void)> get_incrementer() {
    return []() {
        static int count = 0;
        return count++;
    };
}

std::function<int (void)> get_incrementer() {
    int count = 0;
    return [count]() mutable {
        return count++;
    };
}
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,返回函数的每个实例将共享相同的增量计数.在第二种情况下,每次调用时get_incrementer,您将获得一个单独的对象,其中包含自己的增量计数.

用户想要哪一个?目前尚不清楚.所以你不能随便"纠正"它.