在多集合中查找结构的语法 - C ++

时间:2010-05-12 22:35:15

标签: c++ map struct set

我似乎无法弄清楚在容器中查找结构的语法。

我有一组多Event个结构。我试图通过搜索它的键找到其中一个结构。我在下面评论了编译器错误。

struct Event {
 public:
  bool operator < ( const Event & rhs ) const {
    return ( time < rhs.time );
  }
  bool operator > ( const Event & rhs ) const {
    return ( time > rhs.time );
  }
  bool operator == ( const Event & rhs ) const {
    return ( time == rhs.time );
  }

  double time;
  int eventID;
  int hostID;
  int s; 
};

typedef std::multiset< Event, std::less< Event > > EventPQ;

EventPQ currentEvents;
double oldRecTime = 20.0;
EventPQ::iterator ceItr = currentEvents.find( EventPQ::key_type( oldRecTime ) ); // no matching function call

我尝试了几种排列无济于事。我认为定义条件相等运算符就足够了。


解决方案

在纠正我的拼写错误之后(抱歉),我现在有一个最接近AraK的解决方案,并通过Soapbox建议使用explicit来增强:

struct Event { 
   explicit Event(double t) : time(t), eventID(), hostID(), s() {}
   Event(double t, int eid, int hid, int stype) : time(t), eventID( eid ), hostID( hid ), s(stype) {}
   ... 
};

EventPQ::iterator ceItr = currentEvents.find( EventPQ::key_type( Event(oldRecTime) ) ); 

我最近发现另一种选择是使用find_if,讨论here

感谢您的帮助。

3 个答案:

答案 0 :(得分:3)

您没有合适的接受double的构造函数。只需添加以下构造函数:

Event(double t) : time(t), eventID(/**/), hostIDeventID(/**/), s(/**/)
{ }

以下是事件的样子:

struct Event {
 public:
 // Initialize other variables as needed
 Event(double t) : time(t), eventID(/**/), hostIDeventID(/**/), s(/**/)
 { }

  bool operator < ( const Event & rhs ) const {
    return ( time < rhs.time );
  }
  bool operator > ( const Event & rhs ) const {
    return ( time > rhs.time );
  }
  bool operator == ( const Event & rhs ) const {
    return ( time == rhs.time );
  }

  double time;
  int eventID;
  int hostID;
  int s; 
};

// No need for std::less because it is used by default,
// when you define 'operator <' in your class
typedef std::multiset< Event > EventPQ;

EventPQ currentEvents;
double oldRecTime = 20.0;
// You can just pass the double, a temporary object will be created
// for you.
EventPQ::iterator ceItr = currentEvents.find( oldRecTime );

答案 1 :(得分:2)

除了缺少的构造函数之外,您不希望在迭代器find()上调用ceItr,而是调用currentEvents

EventPQ::iterator ceItr = currentEvents.find(EventPQ::key_type(oldRecTime));

请注意,find()仅为您提供第一个匹配的迭代器,使用equal_range()获取所有匹配的范围:

std::pair<EventPQ::iterator, EventPQ::iterator> result;
result = currentEvents.find(EventPQ::key_type(oldRecTime));

for(EventPQ::iterator it = result.first; it != result.second; ++it) {
    // do stuff
}

答案 2 :(得分:0)

您似乎对multiset和multimap感到困惑。 Multiset用于键和值是同一个时。 Multimap用于关键字和值关联,但不是同一个对象。

在这种情况下,Event实际上并不是关键。 “时间”双重似乎是关键。由于键和值不完全相同,因此应使用多图。使用事件作为键和值在这里没有意义。

您不希望构建具有额外字段的事件,而不仅仅是搜索给定值。相反,multimap允许您使用double进行搜索,这正是您真正想要的。这也消除了Event类中少于运算符的需要。

您的代码看起来像这样:

struct Event {
  double time;
  int eventID;
  int hostID;
  int s; 
};

typedef std::multimap<double, Event> EventPQ;

EventPQ currentEvents;
double oldRecTime = 20.0;
std::pair<EventPQ::iterator, EventPQ::iterator> results = currentEvents.equal_range(oldRecTime);

for(EventPQ::iterator cur = results.first; cur != results.second; ++cur) {
    // do something to *cur
}