【问题标题】:Priority Queue with lambda function error具有 lambda 函数错误的优先级队列
【发布时间】:2018-04-18 07:48:40
【问题描述】:

这一切都在一个类中。 B 类持有一个列表。

class A{
   bool compare = [](const B& lhs, const B& rhs){
     return lhs.list.size() >= rhs.list.size();
   };

   priority_queue<B, vector<B>, decltype(compare)> pq(compare);
};

我在 pq 上遇到任何错误。我对 lambda 函数非常不熟悉,所以我不知道如何解决这个函数。

错误:比较不是类型

【问题讨论】:

  • 题外话:为什么不只是一个常规的、普通的、静态的成员函数?这里没有需要使用 lambda。
  • @StoryTeller 这个比较函数将有多个返回值。因此,我将使用 switch 语句访问 A 类中的成员,该成员将决定比较将返回什么返回值。编辑:除非您知道比较器有多个返回的方法。
  • 这个 lambda(假设它是“固定的”)也不会帮助你做到这一点......
  • @Plays4u 然后你需要访问函数内部的A 实例,所以你需要一个成员函数和/或一个捕获lambda。
  • 在我看来,如果你需要替换它所代表的函数,在这里使用 lambda 是有意义的。 @StoryTeller:“固定”的 lambda 是没用的,不是吗? lamdbas 可以在一个方面的实现之间进行更改。

标签: c++ c++11 lambda priority-queue


【解决方案1】:

成员comparebool,不是函数,它的值是true。从您的 lambda 类型到 bool(*)(const B&amp;, const B&amp;) 的隐式转换,然后从函数指针类型到 bool 的转换。如果您要向捕获列表中添加任何内容,则该行将失败,因为有状态 lambda 不会转换为函数指针。

你不能声明数据成员auto,所以如果你想让它成为一个lambda,它就不能在类范围内。但你不需要它,静态函数可以正常工作。

class A{
   static bool compare(const B& lhs, const B& rhs) {
     return lhs.list.size() >= rhs.list.size();
   }; 

   std::priority_queue<B, std::vector<B>, decltype(compare)> pq;
public:
   A():pq(compare){}
};

【讨论】:

    【解决方案2】:

    有几件事需要改变。首先,lambda 声明很奇怪。 Lambda 在最后给出它们的返回值(虽然我认为这是允许的,但在我看来可能被解读为试图将 lambda 分配给 bool 变量。

    其次,我无法对捕获 lambda 的实际类型的 auto 或类似关键字执行相同操作,因为这意味着静态 constexpr 与您所拥有的相去甚远。

    因此,我明确地为 lambda 提供了一个好的类型(请注意,lambda 的类型总是很奇怪,因此在许多情况下,如果您想要可读的错误消息和这几乎从来都不是问题。如果您不知道签名,您很可能必须对其进行模板化。但是,带有 lambda 的类也将被模板化,没有问题。

    最后,用元素初始化队列是不正确的,因为可能很难以正确的顺序构造所有对象。因此,初始化已经移到了A的构​​造函数中。

    这是我的更正:

    #include<queue>
    #include<list>
    #include<vector>
    #include<functional>
    
    using namespace std;
    
    struct B{
      std::list<int> list;
    };
    
    class A{
       function<bool(const B&, const B&)> compare = [](const B& lhs, const B& rhs) ->bool{
         return lhs.list.size() >= rhs.list.size();
       }; 
    
       std::priority_queue<B, vector<B>, decltype(compare)> pq;
       A():pq(compare){}
    };
    
    
    int main()
    {
    }
    

    最后请注意,我不喜欢将 B 的成员命名为 list,因为 list 也是类型。

    【讨论】:

    • Lambda 类型并不“奇怪”,它们只是未命名。
    • list 不是B::list 的类型,它是std::list。尽管如此,list 仍然是一个对象的坏名
    猜你喜欢
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 2011-01-18
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 2011-05-26
    相关资源
    最近更新 更多