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

发布于 2024-09-01 04:06:15 字数 1343 浏览 1 评论 0原文

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

我有多个 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

感谢您的帮助。

I can't seem to figure out the syntax for finding structs in containers.

I have a multiset of Event structs. I'm trying to find one of these structs by searching on its key. I get the compiler error commented below.

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

I've tried a few permutations to no avail. I thought defining the conditional equality operator was going to be enough.


Solution

After correcting my typo (sorry), I now have a solution closest to AraK's, augmented by Soapbox's suggested use of 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) ) ); 

I recently discovered that another option would have been to use find_if, discussed here.

Thanks for the help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

奢望 2024-09-08 04:06:15

您没有合适的接受 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 );

You don't have a suitable constructor that accepts double. Just add the following constructor:

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

Here is how Event would look like:

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 );
且行且努力 2024-09-08 04:06:15

除了缺少构造函数之外,您不想在迭代器 ceItr 上调用 find(),而是在 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
}

Besides the missing constructor, you don't want to call find() on the iterator ceItr but on currentEvents:

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

Note that find() only gives you an iterator to the first match, use equal_range() to get a range of all matches:

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
}
蓝海似她心 2024-09-08 04:06:15

您似乎混淆了多重集和多重映射。多重集适用于键和值相同的情况。 Multimap 适用于键和值关联但不是同一对象的情况。

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

您不想构造一个带有额外字段的事件,您不需要只是为了搜索给定值。相反,多重映射允许您使用双精度进行搜索,这才是您真正想要的。这也消除了 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
} 

You seem to have multiset and multimap confused. Multiset is for when the key and the value are one-and-the-same. Multimap is for when a key and a value are associated, but not the same object.

In this case, Event isn't actually the key. The "time" double appears to be the key. Since the key and the value are not exactly the same, you should use a multimap. Using event as both the key and value doesn't make sense here.

You don't want to construct an event with extra fields you don't need just to search for a given value. Instead, multimap lets you search using the double, which is what you really want. This also eliminates the need for less than operators in the Event class.

Your code would then look something like this:

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
} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文