gpt4 book ai didi

c++ - 带有 std::function 的通用 lambda 不捕获变量

转载 作者:IT老高 更新时间:2023-10-28 12:51:22 25 4
gpt4 key购买 nike

我正在尝试使用 C++14 的通用 lambda,但遇到了 std::function 问题。

#include <iostream>
#include <functional>

int main()
{
const int a = 2;
std::function<void(int)> f = [&](auto b) { std::cout << a << ", " << b << std::endl; };
f(3);
}

编译失败并显示错误消息,指出 error: ‘a’ is not declared in this scope.

如果我把它改成 (int b) 就可以了。

这是一个错误吗?还是我错过了什么?

我使用的 GCC 版本是 4.9.2。

最佳答案

除非我执行以下任何操作,否则我可以重现此内容:

  • 移除 const来自 a
  • 姓名a捕获列表
  • 更改 std::function<void(int)>auto
  • 通过更改 auto b 使 lambda 成为非泛型至int b
  • 使用 Clang(例如 v3.5.0)

我认为这是一个与优化相关的编译器错误,并且未能在通用 lambda 中检测到 odr-use(有趣的是,设置 -O0 没有效果)。它可能与 bug 61814 有关但我不认为这是相当同一件事,因此:

我已将其提升为 GCC bug 64791 .

  • (更新:此错误已在 GCC 5.0 中标记为已修复。)

当然,我在 C++14 的措辞中找不到任何明显的不应该允许您的代码的内容,尽管在新的 C++14 措辞中通常很少有“明显的”。 :(


[C++14: 5.1.2/6]: [..] For a generic lambda with no lambda-capture, the closure type has a public non-virtual non-explicit const conversion function template to pointer to function. The conversion function template has the same invented template-parameter-list, and the pointer to function has the same parameter types, as the function call operator template. [..]

[C++14: 5.1.2/12]: A lambda-expression with an associated capture-default that does not explicitly capture this or a variable with automatic storage duration (this excludes any id-expression that has been found to refer to an init-capture's associated non-static data member), is said to implicitly capture the entity (i.e., this or a variable) if the compound-statement:

  • odr-uses (3.2) the entity, or
  • names the entity in a potentially-evaluated expression (3.2) where the enclosing full-expression depends on a generic lambda parameter declared within the reaching scope of the lambda-expression.

[ Example:

void f(int, const int (&)[2] = {}) { } // #1
void f(const int&, const int (&)[1]) { } // #2
void test() {
const int x = 17;
auto g = [](auto a) {
f(x); // OK: calls #1, does not capture x
};

auto g2 = [=](auto a) {
int selector[sizeof(a) == 1 ? 1 : 2]{};
f(x, selector); // OK: is a dependent expression, so captures x
};
}

—end example ] All such implicitly captured entities shall be declared within the reaching scope of the lambda expression. [ Note: The implicit capture of an entity by a nested lambda-expression can cause its implicit capture by the containing lambda-expression (see below). Implicit odr-uses of this can result in implicit capture. —end note ]

[C++14: 5.1.2/13]: An entity is captured if it is captured explicitly or implicitly. An entity captured by a lambda-expression is odr-used (3.2) in the scope containing the lambda-expression. [..]

关于c++ - 带有 std::function 的通用 lambda 不捕获变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28141403/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com