c++ - const static auto lambda 与引用捕获一起使用

标签 c++ c++11 lambda reference

在 C++11 函数中使用一些本地 lambda 对象时,我很想将它们声明为 const static auto lambda = ...只是为了让编译器知道只有一个 std::function需要对象(并可能优化调用和/或内联它),但我意识到在这种情况下通过引用捕获局部值会导致奇怪的行为。

考虑以下代码:

void process(const Data& data, const std::function<void(DataElement&>& lambda) {
  ...
}

void SomeClass::doSomething()
{
  int foo = 0;

  const static auto lambda = [&foo] () { .... ++foo; .... }

  process(data, lambda);
}

这不适用于多次调用 doSomething()但机制尚不清楚。

  • foo在第一次调用时绑定(bind),然后保持绑定(bind)到堆栈地址,该地址在连续调用时变得无效?
  • 我是不是被迫放弃了static在这种情况下?

标准中哪里规定了这种行为?考虑到它是 static变量在哪里构建?懒惰地第一次调用 doSomething() (以便第一次调用有效)或在程序启动时?

最佳答案

当控制流第一次到达它的声明时,一个静态函数作用域变量被“懒惰地”初始化。这意味着通过引用捕获确实绑定(bind)到当前在堆栈上的 foo,并且当调用终止时,该绑定(bind)变为悬空。

不要试图过多地帮助编译器;使 lambda static 看起来像是微优化,具有非常糟糕的副作用。实际创建闭包对象几乎没有任何开销,而且无论它是否为 static,编译器都可以轻松地将其内联。

更不用说,即使使用您的方法,您也没有节省创建 std::function 对象的费用。 lambda 表达式的类型是未命名的闭包对象,不是 std::function。因此,即使 lambdastaticstd::function 对象无论如何都会在每次调用中创建(除非整个对象都是内联的)。

关于c++ - const static auto lambda 与引用捕获一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30999807/

相关文章:

c++ - 是否可以为每个循环删除 c++11 中 std::list 的元素

java - docs.oracle.com lambda 表达式示例无法编译

c# - 如何在此 lambda 表达式中指定 "not in"?

c# - 托管 C++ 将 float *OUT 作为参数传递

c++ - 用泰勒法 C++ 计算圆周率

c++ - 删除的默认构造函数仍然是微不足道的吗?

java - 为什么实例方法的Java Method Reference不能赋值给Consumer接口(interface)

c++ - 额外的继承对对象结构或实例化有什么影响吗?

c++ - 在以下程序中使用 C++ 获取 SIGABRT

c++ - 什么时候返回右值引用会导致未定义的行为?