【问题标题】:C++ : How to define map of priority queues using lambda comparator?C++:如何使用 lambda 比较器定义优先级队列映射?
【发布时间】:2021-04-03 19:31:02
【问题描述】:

你可以用 lambda 定义优先级队列

auto cmp = [] (const MyClass& a, const MyClass& b) -> bool{return a.v2 > b.v2};
priority_queue<MyClass, std::vector<MyClass>, decltype(cmp)> pq(cms);

当我使用函数对象(自定义比较)定义优先队列的映射时,没有错误。

   unordered_map<int, priority_queue<int, std::vector<int>, greater<int>> my_map;

但是当我使用相同的技术(使用 lambda 进行自定义比较)来定义优先级队列的映射时,我得到了错误。

unordered_map<MyKeyClass, priority_queue<MyClass, std::vector<MyClass>, decltype(cmp)>> my_map;

错误

/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/queue:447:16: error: no matching constructor for initialization of 'std::__1::priority_queue<int, std::__1::vector<int, std::__1::allocator<int>
      >, (lambda at avg5.cpp:13:24)>::value_compare' (aka '(lambda at avg5.cpp:13:24)')
        : c(), comp() {}
               ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/tuple:1401:7: note: in instantiation of member function 'std::__1::priority_queue<int, std::__1::vector<int, std::__1::allocator<int> >,
      (lambda at avg5.cpp:13:24)>::priority_queue' requested here
      second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
      ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/utility:507:11: note: in instantiation of function template specialization 'std::__1::pair<const int, std::__1::priority_queue<int,
      std::__1::vector<int, std::__1::allocator<int> >, (lambda at avg5.cpp:13:24)> >::pair<const int &, 0>' requested here
        : pair(__pc, __first_args, __second_args,
          ^

如何使用 lambda 定义和填充具有自定义比较的优先级队列映射?

【问题讨论】:

  • 如果auto cmp = [] (const MyClass&amp; a, const MyClass&amp; b){//comparison code}; 中没有return,则返回类型为void。您能否添加比较器返回的内容。
  • @RichardCritten 没有回报?它的比较器,所以它不应该返回 bool 吗?
  • 如果没有return 语句,&lt;lambda&gt;::operator(const MyClass&amp; a, const MyClass&amp; b) 的推导返回类型将是void,即不是一个有效的比较器。没有return,我们就没有minimal reproducible example
  • @RichardCritten 公平点..我已经返回 bool(问题现已更新)但仍面临问题
  • 您必须将编译器升级到支持 C++20 的编译器。在 c++20 之前,lambda 不是默认可构造的,并且不能被赋值运算符复制(如果它们是无捕获的)。错误很明显 -> comp(),这是您的比较器的默认创建 - 在 c++20 之前不允许使用 lambda 类型。

标签: c++ c++17 priority-queue


【解决方案1】:

您不应操纵 lambda 的类型。在您的情况下,您应该使用std::function。以下是标准对 lambda 类型的说明:

lambda 表达式是唯一的未命名非联合非聚合类类型的纯右值表达式,称为闭包类型,它在最小的块作用域、类作用域或命名空间作用域中声明(为了 ADL 的目的)包含 lambda 表达式。 [...]
除了函数体和函数的默认参数之外,未计算的表达式、模板参数、别名声明、typedef 声明以及函数(或函数模板)声明中的任何地方都不允许使用 Lambda 表达式。

您可以找到有关此herehere 的更多信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-07
    • 2021-06-17
    • 1970-01-01
    相关资源
    最近更新 更多