c++ - Lambda 隐式捕获因从结构化绑定(bind)声明的变量而失败

标签 c++ lambda visual-studio-2017 c++17 structured-bindings

使用以下代码,我得到一个编译错误 C2065 'a': undeclared identifier(使用 visual studio 2017):

[] {
    auto [a, b] = [] {return std::make_tuple(1, 2); }();
    auto r = [&] {return a; }(); //error C2065
}();

但是,下面的代码可以编译:

[] {
    int a, b;
    std::tie(a, b) = [] {return std::make_tuple(1, 2); }();
    auto r = [&] {return a; }();
}();

我认为这两个样本是等价的。是编译器错误还是我遗漏了什么?

最佳答案

Core issue 2313更改了标准,以便结构化绑定(bind)永远不会是变量的名称,从而使它们永远无法捕获。

P0588R1对 lambda 捕获措辞的重新表述使这一禁令变得明确:

If a lambda-expression [...] captures a structured binding (explicitly or implicitly), the program is ill-formed.

请注意,这个措辞应该是一个占位符,而委员会会弄清楚这种捕获应该如何工作。

由于历史原因保留之前的答案:


这在技术上应该可以编译,但是这里的标准中存在一个错误。

标准说 lambda 只能捕获变量。它说非元组类结构化绑定(bind)声明不会引入变量。它引入了名称,但这些名称不是变量名称。

另一方面,类似元组的结构化绑定(bind)声明确实引入了变量。 auto [a, b] = std::make_tuple(1, 2); 中的 ab 是实际的 引用类型变量。所以它们可以被 lambda 捕获。

显然这不是一个理智的事态,委员会知道这一点,因此应该会尽快修复(尽管对于捕获结构化绑定(bind)应该如何工作似乎存在一些分歧)。

关于c++ - Lambda 隐式捕获因从结构化绑定(bind)声明的变量而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54842919/

相关文章:

c# - 在 lambda 表达式中分配局部变量

java - 常规闭包内部如何工作?

asp.net-mvc - 调试时编辑 .NET Core cs 文件

visual-studio-2017 - 指定的任务可执行位置 "...\packages\Microsoft.Net.Compilers.1.3.2\build\..\tools\csc.exe"无效

c++ - C++ 中的多模型构建(迭代)(多场景 Benders 分解)

c++ - 在我的 C++ 应用程序中包含第三方代码时出现问题

c++ - C++ 中的方法覆盖

c++ - 有没有办法让 `enum` 类型无符号?

haskell - 与 lambda 表达式组合 haskell

azure - 如何将 Visual Studio Azure Functions 项目(多个函数)发布到不同的 Azure Function 应用