【问题标题】:priority_queue with custom cmp具有自定义 cmp 的 priority_queue
【发布时间】:2021-09-01 23:11:26
【问题描述】:

我尝试实现按事件字段排序的事件队列。 所以我写了这样的东西:

struct MyAlgo 
{
   MyAlgo() {
      // some random generation of positions
      for (auto pos : RandomPostions)
        Queue.push({SiteEvent, pos, NULL});
   }
   struct Event
   {
      EventType Type;
      FVector2D Pos;
      Node* Arc;
   }
   bool cmp(const Event& a, const Event& b) { return a.Pos.Y > a.Pos.Y; }
   std::priority_queue<Event, std::vector<Event>, decltype(&cmp)> Queue;
}

在我的队列中没有有序元素。怎么了?

【问题讨论】:

标签: c++ queue


【解决方案1】:

您需要一个静态函数(以匹配比较操作的签名)。此外,您需要限定名称:

static bool cmp(const Event& a, const Event& b) {
    return a.Pos.Y > b.Pos.Y;
}
std::priority_queue<Event, std::vector<Event>, decltype(&MyAlgo::cmp)>
    Queue { &MyAlgo::cmp };

另外,请注意比较本身存在缺陷(它将变量与自身进行比较,导致Undefined Behaviour,因为弱总排序不一致。

简化

将比较器改为函数对象:

struct Cmp {
    bool operator()(const Event& a, const Event& b) const {
        return a.Pos.Y > b.Pos.Y;
    }
};
std::priority_queue<Event, std::vector<Event>, Cmp> Queue;

现在你不能忘记将 cmp 实例传递给构造函数。

现场演示

Live On Coliru

#include <queue>
#include <iostream>
#include <array>

enum class EventType { SiteEvent };
struct FVector2D {
    float X, Y;
    friend std::ostream& operator<<(std::ostream& os, FVector2D const& fv)
    {
        return os << "{" << fv.X << "," << fv.Y << "}";
    }
};

struct Node {
};

struct MyAlgo {
    MyAlgo()
    {
        // some random generation of positions
        for (auto pos : {FVector2D{1, 22}, {2, 3}, {8, 33}}) {
            Queue.push({EventType::SiteEvent, pos, nullptr});
        }
    }

    struct Event {
        EventType Type;
        FVector2D Pos;
        Node*     Arc = nullptr;

        friend std::ostream& operator<<(std::ostream& os, Event const& ev) {
            return os << ev.Pos;
        }
    };

    struct Cmp {
        bool operator()(const Event& a, const Event& b) const {
            return a.Pos.Y > b.Pos.Y;
        }
    };
    std::priority_queue<Event, std::vector<Event>, Cmp> Queue;
};

int main()
{
    MyAlgo algo;

    while (not algo.Queue.empty()) {
        std::cout << algo.Queue.top() << "\n";
        algo.Queue.pop();
    }
}

打印

{2,3}
{1,22}
{8,33}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-09
    • 1970-01-01
    • 2011-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多