Reputation: 15
class Event{
public:
enum EventType { A_1, A_2, A_3, A_4};
Event(EvtType type = A_1, double etime = 0.0)
: _type(type)
, _etime(etime)
{}
EventType get_Type() const { return _type; };
double get_Time() const { return _etime; }
protected:
EventType _type;
double _etime;
};
struct EventLess{
bool operator()(const Event& lhs, const Event& rhs) const
{
return (lhs.get_Time() > rhs.get_Time());
}
};
I can create min priority queue as below
priority_queue<Event, std::vector<Event>, EventLess> q;
However, if I have another class like:
class Event1
{
public:
enum EventType { disruption_1, disruption_2};
Event(EvtType type = disruption_1, double htime = 0.0, double duration)
: _type(type)
, _htime(htime)
, _duration(duration)
{}
EventType get_Type() const { return _type; };
double get_Time() const { return _htime; }
double get_Duration() const { return _duration; }
protected:
EventType _type;
double _etime;
double _duration;
};
and I want to create the min priority queue of these two classes (Time comparing). Please anyone demonstrate me how to solve this will be thankful.
After receiving suggestion, I have improved a code by using inheritance as presented.
#include <queue>
#include <iostream>
using namespace std;
class IEvent{
public:
IEvent(double time_e): Etime(time_e) {}
virtual double get_Time() const {return Etime;}
protected:
double Etime;
};
class Event1:public IEvent{
public:
enum EType1 { A_1, A_2, A_3, A_4};
Event1(EType1 type1, double time_e, int _speed)
: _type1(type1)
, IEvent(time_e)
, speed(_speed)
{}
virtual EType1 get_Type() const { return _type1; };
virtual double get_Time() const { return Etime; }
int get_speed() const {return speed;}
private:
EType1 _type1;
int speed;
};
class Event2:public IEvent{
public:
enum EType2 { disruption_1, disruption_2};
Event2(EType2 type2, double time_e, double duration)
: _type2(type2)
, IEvent(time_e)
, _duration(duration)
{}
virtual EType2 get_Type() const { return _type2; };
virtual double get_Time() const { return Etime; }
double get_duration() const { return _duration; }
private:
EType2 _type2;
double _duration;
};
struct IEventLess{
bool operator()(const IEvent& lhs, const IEvent& rhs) const
{
return (lhs.get_Time() > rhs.get_Time());
}
};
int main(){
priority_queue<IEvent, vector<IEvent>, IEventLess> q;
q.push(Event1(Event1::A_1, 15.0, 10));
q.push(Event2(Event2::disruption_1, 5.0, 5.0));
IEvent *evt;
evt = new q.top();
cout << evt.get_Type() << evt.get_Time() << endl;
}
Nevertheless, I still have some problem in calling other function in derived class, and a little bit confusing when calling top() function as show in main function.
Please anyone help me solve it out.
Thank you.
Upvotes: 0
Views: 746
Reputation: 69864
boost::variant
removes the need for a common base class or inheritance:
#include <queue>
#include <boost/variant.hpp>
class Event{
public:
enum EventType { A_1, A_2, A_3, A_4};
Event(EventType type = A_1, double etime = 0.0)
: _type(type)
, _etime(etime)
{}
EventType get_Type() const { return _type; };
double get_Time() const { return _etime; }
protected:
EventType _type;
double _etime;
};
inline double get_time(const Event& e) {
return e.get_Time();
}
class Event1
{
public:
enum EventType { disruption_1, disruption_2};
Event1(EventType type = disruption_1, double htime = 0.0, double duration = 0)
: _type(type)
, _etime(htime)
, _duration(duration)
{}
EventType get_Type() const { return _type; };
double get_Time() const { return _etime; }
double get_Duration() const { return _duration; }
protected:
EventType _type;
double _etime;
double _duration;
};
inline double get_time(const Event1& e) {
return e.get_Time();
}
// name predicates properly
struct EventGreater{
template<class L, class R>
bool operator()(const L& lhs, const R& rhs) const
{
return get_time(lhs) > get_time(rhs);
}
};
template<class...Ts>
double get_time(const boost::variant<Ts...>& var)
{
return boost::apply_visitor([](auto& x) { return get_time(x); }, var);
}
struct event_handler : boost::static_visitor<void>
{
void operator()(const Event& e) const
{
// handle an Event in here
}
void operator()(const Event1& e) const
{
// handle an Event1 in here
}
};
int main()
{
using EventVariant = boost::variant<Event, Event1>;
// we all know that a priority queue inverts the predicate
std::priority_queue<EventVariant, std::vector<EventVariant>, EventGreater> q;
q.push(Event());
q.push(Event1());
//
// remove an item and action it
auto ev = std::move(q.top());
q.pop();
boost::apply_visitor(event_handler(), ev);
}
Upvotes: 6
Reputation: 4245
Have both Event
and Event1
inherit from a common base.
class IEvent
{
public:
virtual double get_Time() = 0;
};
class Event : public IEvent
{
public:
virtual double get_Time() {...}
}
class Event1 : public IEvent
{
public:
virtual double get_Time() {...}
}
You can then store the base pointers in the queue, and cast to the concrete child when needed.
std::priority_queue<std::shared_ptr<IEvent>, std::vector<IEvent>, IEventLess> q;
auto Time = q.front()->get_Time();
Upvotes: 2