40

结构化绑定使遍历具有基于范围的 for 循环的地图更加清晰和可读,如下所示

for (auto [key, value] : map) {
    cout << key << " : " << value << endl;
}

但是结构化绑定可以在如下 lambda 表达式中使用吗?

std::for_each(map.begin(), map.end(), [](auto [key, value]) {
    cout << key << " : " << value << endl;
});

从看起来上面的代码不适用于我在这里找到的在线 C++ 编译器https://wandbox.org/permlink/sS6r7JZTB3G3hr78

如果它不起作用,那么是否有充分的理由不支持上述内容?还是只是尚未提出的东西?模板只会在使用时被实例化,因此结构化绑定的“解除绑定”过程可以发生在请求实例化的地方(即调用函数时)

4

2 回答 2

32

语法当前不允许这样做;结构化绑定是一个简单的声明

简单声明:[...]
-属性说明符序列opt decl 说明符序列 ref 限定符opt [ 标识符列表 ] 初始值设定项 ;

而函数参数由parameter-declaration-list引入,其中包含声明符:

*声明符指定这些实体的名称,并(可选地)使用(指针)和()(函数返回)等运算符修改说明符的类型。

也就是说,结构化绑定是(块级)语句语法 - 您可以通过注意它的语法以分号结尾来看到这一点;。在 lambda 参数列表中允许结构化绑定需要添加额外的语法。

这听起来是个好主意,而且我看不出语法上有任何歧义。这当然值得讨论,因为它比替代方案更好、更简洁地解决了您提出的用例。

于 2017-08-07T07:55:03.157 回答
2

我认为这将是一个很棒的提议(如果还没有的话),它将简化传递 zip 迭代器/引用元组的算法的代码。(例如https://github.com/correaa/iterator-zipper

同时,通过提取函数第一行中的结构,使用更详细的代码似乎不是您无法实现的:

#include <algorithm>
#include <iostream>
#include <map>

using std::cout;
using std::endl;

int main(){
    auto map = std::map<int, int>{{1, 2}};
    std::for_each(map.begin(), map.end(), [](auto const& key_value){
        auto const& [key, value] = key_value;
        cout<< key <<" "<< value <<endl;
    });
}

https://wandbox.org/permlink/sS6r7JZTB3G3hr78

(这加强了这一点,即这是可实现的并且易于添加到语言中)。

更精简的版本可以缩进为:

    [](auto const& _){auto&& [key, value] = _; // [](auto const& [key, value]){
        cout<< key <<" "<< value <<endl;
    }
于 2020-10-24T01:27:08.667 回答