gpt4 book ai didi

c++ - 修改 unique_ptr 的 priority_queue

转载 作者:搜寻专家 更新时间:2023-10-31 01:06:23 24 4
gpt4 key购买 nike

我正在尝试用 C++ 编写事件驱动的模拟。现在它只是基本事件类的 unique_ptr 的基本优先级队列:

class Event
{
public:
double time;
Event(double time);
virtual void handle() = 0;
};

struct EventCompare
{
bool operator()(std::unique_ptr<Event> e1, std::unique_ptr<Event> e2) {
return e1->time > e2->time;
}
};

class DumpSimulationEvent : public Event
{
public:
DumpSimulationEvent(const double time);
void handle();
};

typedef std::priority_queue<std::unique_ptr<Event>, std::vector<std::unique_ptr<Event>>, EventCompare> EventQueue;

class Simulation
{
double time;
EventQueue eventQueue;
public:
Simulation();
void run();
};

Event::Event(const double t)
{
time = t;
}

DumpSimulationEvent::DumpSimulationEvent(const double t) : Event(t)
{
}

void DumpSimulationEvent::handle()
{
std::cout << "Event time: " << time;
}

Simulation::Simulation()
{
time = 0;
eventQueue = EventQueue();
std::unique_ptr<DumpSimulationEvent> dumpEvent5(new DumpSimulationEvent(5));
//eventQueue.emplace(dumpEvent5);
}

void Simulation::run()
{
while (!eventQueue.empty()) {
std::unique_ptr<Event> currentEvent = std::move(eventQueue.top());
//eventQueue.pop();
time += currentEvent->time;
currentEvent->handle();
}
}

Main 函数(上面未显示)只是创建一个 Simulation 实例并调用 run() 方法。问题是取消注释 emplace() 或 pop() 会导致

error C2280: 'std::unique_ptr<Event,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' : attempting to reference a deleted function  c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility 521 1

研究表明最有可能的原因是试图复制 unique_ptr。然而,我不知道它是否是真正的原因,它是否真的发生在注释行或只是在那里变得可见。添加 std::move 到 emplace 参数似乎没有帮助。

最佳答案

你的问题是你没有正确移动东西,但你试图在几个地方制作拷贝。

这是一个让您的代码正常工作的差异,带有一些注释:

 struct EventCompare
{
- bool operator()(std::unique_ptr<Event> e1, std::unique_ptr<Event> e2) {
+ bool operator()(std::unique_ptr<Event> const &e1, std::unique_ptr<Event> const &e2) {
return e1->time > e2->time;
}
};

这里,正如 juanchopanza 在他的回答中提到的,你必须通过引用而不是值来获取 std::unique_ptr,否则你要求编译器为你制作拷贝,这不是允许。

     time = 0;
eventQueue = EventQueue();
std::unique_ptr<DumpSimulationEvent> dumpEvent5(new DumpSimulationEvent(5));
- //eventQueue.emplace(dumpEvent5);
+ eventQueue.emplace(std::move(dumpEvent5));
}

在上面的代码中,您必须将 std::unique_ptr 移动到队列中。 Emplace 不会神奇地移动东西,它只是将参数转发给构造函数。此处没有 std::move,您要求制作一个拷贝。您也可以只编写:eventQueue.emplace(new DumpSimulationEvent(5)); 并跳过中间对象。

     while (!eventQueue.empty()) {
- std::unique_ptr<Event> currentEvent = std::move(eventQueue.top());
- //eventQueue.pop();
+ std::unique_ptr<Event> currentEvent(std::move(const_cast<std::unique_ptr<Event>&>(eventQueu
+ eventQueue.pop();
time += currentEvent->time;
currentEvent->handle();

最后,在上面的代码中,你试图从 eventQueue.top() 移动,但是你不能从一个 const 引用移动,这就是top() 返回。如果你想强制移动工作,你必须同时使用 const_caststd::move() ,如上所示。

这里是完整的修改后的代码,在这里可以用 g++-4.8 -std=c++11 编译得很好:

#include <memory>
#include <queue>
#include <iostream>

class Event
{
public:
double time;
Event(double time);
virtual void handle() = 0;
};

struct EventCompare
{
bool operator()(std::unique_ptr<Event> const &e1, std::unique_ptr<Event> const &e2) {
return e1->time > e2->time;
}
};

class DumpSimulationEvent : public Event
{
public:
DumpSimulationEvent(const double time);
void handle();
};

typedef std::priority_queue<std::unique_ptr<Event>, std::vector<std::unique_ptr<Event>>, EventCompare> EventQueue;

class Simulation
{
double time;
EventQueue eventQueue;
public:
Simulation();
void run();
};

Event::Event(const double t)
{
time = t;
}

DumpSimulationEvent::DumpSimulationEvent(const double t) : Event(t)
{
}

void DumpSimulationEvent::handle()
{
std::cout << "Event time: " << time;
}

Simulation::Simulation()
{
time = 0;
eventQueue = EventQueue();
std::unique_ptr<DumpSimulationEvent> dumpEvent5(new DumpSimulationEvent(5));
eventQueue.emplace(std::move(dumpEvent5));
}

void Simulation::run()
{
while (!eventQueue.empty()) {
std::unique_ptr<Event> currentEvent(std::move(const_cast<std::unique_ptr<Event>&>(eventQueue.top())));
eventQueue.pop();
time += currentEvent->time;
currentEvent->handle();
}
}

关于c++ - 修改 unique_ptr 的 priority_queue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20908230/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com