使用以下代码,我得到一个编译错误 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; }();
}();
我认为这两个样本是等价的。是编译器错误还是我遗漏了什么?
原文由 ThreeStarProgrammer57 发布,翻译遵循 CC BY-SA 4.0 许可协议
核心问题 2313 更改了标准,因此结构化绑定永远不是变量的名称,使它们永远无法捕获。
P0588R1 对 lambda 捕获措辞的重新表述明确了这一禁令:
请注意,这个措辞应该是一个占位符,而委员会确切地弄清楚了这种捕获应该如何工作。
由于历史原因保留了以前的答案:
这在技术上应该可以编译,但是这里的标准中有一个错误。
标准规定 lambda 只能捕获变量。它说非元组的结构化绑定声明不会引入变量。它引入了名称,但这些名称不是变量的名称。
另一方面,类似元组的结构化绑定声明 确实 引入了变量。
a
和b
在auto [a, b] = std::make_tuple(1, 2);
是实际的引用类型变量。所以它们可以被 lambda 捕获。显然,这不是一个理智的状态,委员会知道这一点,因此应该会进行修复(尽管对于捕获结构化绑定应该如何工作似乎存在一些分歧)。