可以在多态 lambda 中使用结构化绑定语法吗

Can the structured bindings syntax be used in polymorphic lambdas

结构化绑定使得使用基于范围的 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

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

语法目前不允许这样做;结构化绑定是 simple-declaration:

simple-declaration:[...]
- attribute-specifier-seqopt decl-specifier-seq ref-qualifieropt [ identifier-list ] initializer ;

而函数参数由parameter-declaration-list, which contains declarators:

引入

The declarators specify the names of these entities and (optionally) modify the type of the specifiers with operators such as * (pointer to) and () (function returning).

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

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

我认为这将是一个很棒的提议(如果现在还没有的话),它将简化通过 zip iterators/tuples 引用的算法的代码。(例如 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;
    }