C++多映射查找失败

C++ multimap lookup failing

本文关键字:失败 查找 映射 C++      更新时间:2023-10-16

我使用多映射来存储编码原子反应的对象。多映射看起来像这样:

std::multimap<ReactionElement, ReactionElement> reaction_map;

关键是反应物,价值是产物。然后我遇到一种情况,我找到两个反应物原子,我可以在地图上查找这些反应物可能形成的产物

ReactionElements类的基本内容如下所示:

class ReactionElement {
  friend bool operator==(const ReactionElement& lhs, const ReactionElement& rhs);
  friend bool operator<(const ReactionElement& lhs, const ReactionElement& rhs);
public:
  // Some methods here ...
private:
  // The Atom class tracks the element
  Atom atom_a;
  Atom atom_b;
  // SiteSpecies and NeighborSpecies classes track the reaction geometry
  SiteSpecies site_species_a;
  NeighborSpecies neighbor_species_b;
  // int members track reaction energetics
  int e_initial, e_transition, e_final;
  double reac_distance;
}; // ReactionElement

我从一个文件中读取了一堆ReactionElement和ReactionElement对,并将每个对插入到多映射中。

问题是:当我去取回它们时,只有一些反应是可以访问的。对于某些反应,我可以调用reaction_map.find(reactor),但一无所获。但是,我可以在多映射中进行迭代,并且可以看到我插入的所有对。我用这个作为基本诊断:

for(multimap<ReactionElement, ReactionElement>::iterator it = reaction_map.begin();
    it != reaction_map.end(); ++it)
  std::cout << reaction_map.count(it->first) << 'n';

这打印了一些1、2和。这怎么可能?

有什么想法吗?

(编辑)下面详细介绍了比较运算符。我相当确信每个成员类都是有序的。我会确认的。

// This directly compares each member (using a tolerance of .01 for reac_distance).
bool operator==(const ReactionElement& lhs, const ReactionElement& rhs) {
  return (lhs.atom_a == rhs.atom_a and lhs.atom_b == rhs.atom_b and
      lhs.site_species_a == rhs.site_species_a and
      lhs.neighbor_species_b == rhs.neighbor_species_b and
      lhs.e_initial == rhs.e_initial and lhs.e_transition == rhs.e_transition and
      lhs.e_final == rhs.e_final and
      fabs(lhs.hop_distance-rhs.hop_distance) <= 0.01);
}
// < orders on members in the order they appear in the class definition.
bool operator<(const ReactionElement& lhs, const ReactionElement& rhs) {
  if (lhs.atom_a < rhs.atom_a)
    return true;
  else if (lhs.atom_a == rhs.atom_a and lhs.atom_b < rhs.atom_b) 
    return true;
  else if (lhs.atom_a == rhs.atom_a and lhs.atom_b == rhs.atom_b and 
           lhs.site_species_a < rhs.site_species_a)
    return true;
  // etc for the remaining members.
  return false;
}

迭代与count/find的区别在于countfind必须比较元素(迭代不需要)。默认情况下,std::multimap使用std::less进行比较。这相当于<std::multimap要求这个关系是一个严格的弱序。这尤其意味着以下规则:

  • !(x < x)
  • 如果为(x < y),则为!(y < x)

确保您的operator<实现符合这些规则。如果没有,请更改它,或为std::multimap提供自定义Comparator