使用以下代码,我得到一个编译错误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捕获措辞,使该禁令很明确:



请注意,该措辞据称是占位符,而委员会则明确指出了此类捕获应如何工作。

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

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

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

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

显然,这不是一个理智的状态,委员会知道这一点,因此应该提出解决方案(尽管在捕获结构化绑定(bind)的确切工作方式上存在一些分歧)。

09-10 04:45
查看更多