c++ - C++ lambda 中的静态变量

标签 c++ c++11 lambda

下面的代码工作正常:

#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;
}

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

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

    return [&count]() {
        return count++;
    };
}

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

最佳答案

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++;
    };
}

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

用户想要哪一个?目前还不清楚。所以你不能随便“纠正”它。

关于c++ - C++ lambda 中的静态变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16750933/

相关文章:

c++ - 获取临时地址 [-fpermissive]

c++ - 使用 gcc 编译和使用 clang 编译代码时 undefined reference

c++ - 内联 lambda 初始化程序可以捕获 'this' 指针吗?

C++ UTF-8 字符串

c# - 此查询的 lambda 等价物是什么

c++ - std::equal_range 与 lambda

c++ - Qt 信号/槽和 C++ Lambda 表达式

c++ - 尽管 CudaSuccess,CUDA cudaMemCpy 似乎没有复制

c++ - 是否可以 Hook 子进程发送到 Windows 控制台的消息?

c++ - OS X 上的 libc++ 在哪里?