Lambda 函数在 C++ 中的priority_queue中不起作用(使用 [&] 时)

lambda function doesn't work in priority_queue in c++ (when using [&])

本文关键字:使用 不起作用 C++ 函数 中的 priority queue Lambda      更新时间:2023-10-16

当我做 Leetcode.com 时,无法编译以下代码。

auto cmp=[&](pair<int,int> a, pair<int,int> b){return heightMap[a.first]
[a.second]<heightMap[b.first][b.second];};
priority_queue<pair<int,int>,vector<pair<int,int>>,decltype(cmp)> pq;

当我使用

auto cmp=[](...){return true;}.

但我必须使用

auto cmp=[&](...){...}

因为我需要在函数中访问高度图。

我不知道为什么不能编译

我假设您正在块范围内工作(即在函数内部(。

对于[&][]情况,正确的代码应该是:

priority_queue<pair<int,int>,vector<pair<int,int>>, decltype(cmp)> pq(cmp);
//                                                                   ^^^^^

您可以在 cpp首选项示例中看到这一点。

如果你仔细想想,只有decltype(cmp)pq的定义不可能知道任何局部变量——这种依恋只是在实际创建cmp时形成的。


原因是priority_queue的默认构造函数是(C++17 [priqueue.cons](:

explicit priority_queue(const Compare& x = Compare(), Container&& y = Container());

如您所见,这涉及默认构造类型Compare的对象。在 C++20 之前,lambda 不是默认可构造的。

无状态 lambda 的默认构造是由 P0624 添加的,它没有完全进入 C++17,但现在确实出现在 C++20 草案中。

从技术上讲,C++17编译器甚至应该拒绝[]版本;但似乎一些编译器已经在C++20支持方面领先一步。

我注意到 clang++ 6.0.0 实际上允许默认构造指定为[&]的 lambda,当它发生没有实际捕获变量时;而 P0624 的措辞说这种情况应该被拒绝。也许在 C++20 最终确定之前,这种情况会再次改变。