优先级队列中自定义比较器的访问冲突



我遇到一个问题,我的一个程序抛出了访问冲突。通过调试,我发现由于某种原因,比较器函数为空。然而,我不确定为什么是或如何修复它。

我创建了一个最小的工作示例来重现这个问题:

#include "Tryout.h"
#include <queue>
struct Event {
uint64_t mv_timeout;
};
bool CompareEvents(const Event& a, const Event& b) {
return a.mv_timeout < b.mv_timeout;
}
int main() {
std::priority_queue<Event, std::vector<Event>, decltype(&CompareEvents)> mt_eventQueue;
Event lo_event1{
.mv_timeout = 1,
};
Event lo_event2{
.mv_timeout = 2,
};
mt_eventQueue.push(lo_event1);
mt_eventQueue.push(lo_event2);
return 0;
}

执行时,添加第二个事件时崩溃。

在Tryout.exe中0x0000000000000000抛出异常:0xC0000005:访问冲突执行位置0x0000000000000000.

如前所述,比较函数似乎是空的,即使我通过模板传递它。
这里出了什么问题?

您需要在构造函数中显式指定比较函数

std::priority_queue<Event, std::vector<Event>, decltype(&CompareEvents)> mt_eventQueue( CompareEvents );

否则,比较函数将使用默认实参,并产生空指针。

使用的构造函数具有以下带有默认参数的声明

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

比较器函数的模板参数只提供了函数的类型,您仍然需要提供一个与std::priority_queue实例(通过其构造函数)匹配该类型的实际函数。

如果您自己定义了小于操作符,则不需要显式地为std::priority_queue提供任何其他模板参数。

例如:

struct Event
{
uint64_t mv_timeout;
};
bool operator<(const Event &a, const Event &b)
{
return a.mv_timeout < b.mv_timeout;
}
int main()
{
std::priority_queue<Event> mt_eventQueue;
Event lo_event1{
.mv_timeout = 1,
};
Event lo_event2{
.mv_timeout = 2,
};
mt_eventQueue.push(lo_event1);
mt_eventQueue.push(lo_event2);
return 0;
}

如果比较器函数不是函子,则应该在std::priority:queue的构造函数中传递比较器函数。

std::priority_queue<Event, std::vector<Event>, decltype(&CompareEvents)> mt_eventQueue(CompareEvents);

如果你的比较器是这样的

struct CompareEvents
{
bool operator()(const Event& a, const Event& b) {
return a.mv_timeout < b.mv_timeout;
}
}

您可以在不指定函子的情况下创建队列,只要它将由CompareEvents的默认构造函数推断出来(如这里所述)。

std::priority_queue<Event, std::vector<Event>, CompareEvents> mt_eventQueue; //this works

相关内容

  • 没有找到相关文章

最新更新