【问题标题】:Syntax for finding structs in multisets - C++在多集中查找结构的语法 - C++
【发布时间】:2011-02-18 21:02:37
【问题描述】:

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

我有一组 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

感谢您的帮助。

【问题讨论】:

  • 唯一需要的运算符是operator &lt;,其他都是多余的; a>b 与 b 相同

标签: c++ map struct set


【解决方案1】:

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

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

这是 Event 的样子:

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 );

【讨论】:

  • 你能解释一下你的意思吗?假设多重集中有一个事件对象,其时间成员等于 oldRecTime。为什么我需要一个构造函数来使用 find()? (这里是新手程序员。)
  • 当你将oldRecTime 类型为double 传递给函数时,除非你有一个构造函数,否则你无法构造一个Event 类型的对象。
  • @Sarah,您需要构造函数来创建您传递给find 的密钥。
  • @AraK。我花了一些时间来重载构造函数以使其与我的其余代码相协调。非常感谢,还指出如果定义了
  • @AraK:最后一行的错误与构造函数无关,这是在迭代器而不是容器上调用 .find 的原始代码中的错误。至于构造函数,它应该被声明为显式的。不明确声明意味着编译可以随时将双精度转换为“事件”。这可能会导致一些意想不到的行为,应该避免这种情况,除非“double”和“Event”之间的转换因为它们的相关性而明显(例如 std::string 和 const char* 之间的转换)
【解决方案2】:

除了缺少的构造函数之外,您不想在迭代器 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
}

【讨论】:

  • 抱歉,打错了!感谢 equal_range() 提醒——这最终将是一组具有唯一键的集合。
【解决方案3】:

您似乎对多重集和多重映射感到困惑。 Multiset 适用于键和值相同的情况。 Multimap 适用于键和值关联但不是同一个对象的情况。

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

您不想构建一个包含额外字段的事件,而不仅仅是搜索给定值。相反,multimap 允许您使用双精度搜索,这正是您真正想要的。这也消除了 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
} 

【讨论】:

  • 我真的在尝试使用多重集,对事件结构的时间组件(我在运算符中定义的“键”)进行排序。
  • 您可以使用多图来做到这一点。您将时间用作键,将事件的其余部分用作值。因此,要将“Event e”插入到多图中,您可以: currentEvents.insert(std::make_pair(e.time,e));
  • 对,但是我需要时间属性来保留在 Event 对象中,因为程序中发生了其他事情,并且将其复制到多映射中会产生冗余。
猜你喜欢
  • 2011-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-19
  • 2015-07-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多