C++20下无捕获lambda作std::priority_queue比较器默认构造合法原因问询
结论
这是C20引入的预期行为,触发该变化的核心是C20对无状态lambda类型的规则调整,而非std::priority_queue本身的接口变更。
具体原因
- 首先看你代码里定义的比较器是无捕获的lambda:
#include <queue> int main() { constexpr auto cmp{[](int a, int b) { return a > b; }}; std::priority_queue<int, std::vector<int>, decltype(cmp)> pq; }
在C17及更早的标准中,所有lambda类型都没有默认构造函数,哪怕是无捕获的无状态lambda也不行。你指定std::priority_queue的第三个模板参数为decltype(cmp)时,如果调用默认构造函数,内部会尝试默认构造一个比较器实例,这一步在C17下会编译失败,必须手动给构造函数传入你定义的cmp对象才能正常编译。
- C++20标准修改了lambda的相关规则:没有任何捕获的无状态lambda类型,新增了默认构造和拷贝赋值的支持。你的代码里的lambda完全符合无状态的要求,因此
decltype(cmp)可以被默认构造,std::priority_queue的默认构造函数内部生成的比较器实例和你手动定义的cmp功能完全一致,所以不管是编译还是运行Dijkstra算法都不会出问题。
补充说明
你没有在std::priority_queue的文档中找到相关变更记录是很正常的,因为C++20没有修改std::priority_queue的任何接口逻辑,只是语言层面的lambda规则调整,让原本不满足std::priority_queue默认构造要求的比较器类型,现在满足了要求。
内容的提问来源于stack exchange,提问作者Jay Lee
相关产品推荐
相关产品推荐

