无法将std :: unorded_set与自定义KeyEqual进行比较

时间:2016-03-23 00:32:17

标签: c++ c++11 unordered-set

以下程序无法编译。但如果我不评论operator==,它就会编译。当我已经提供operator==

时,为什么还需要FooEqual
#include <cstddef>
#include <unordered_set>

struct Foo {
};

struct FooHasher {
  size_t operator()(const Foo&) const {
    return 1;
  }
};

struct FooEqual {
  bool operator()(const Foo& lhs, const Foo& rhs) const {
    return true;
  }
};

// bool operator==(const Foo& lhs, const Foo& rhs) {
//   return true;
// }

int main() {
  std::unordered_set<Foo, FooHasher, FooEqual> s1;
  std::unordered_set<Foo, FooHasher, FooEqual> s2;
  (void)(s1 == s2);
  return 0;
}

2 个答案:

答案 0 :(得分:4)

根据http://en.cppreference.com/w/cpp/container/unordered_set/operator_cmp,您实际上需要A, B, C, D进行比较(我现在无法访问标准 - 我会尝试使用特定报价进行更新明天某个时候):

  

如果Key不是EqualityComparable,则行为未定义。

     

如果Hash和KeyEqual没有,则行为也是未定义的   lhs和rhs上的相同行为或者是否是相等比较运算符   for Key不是将分区细化为等效键   KeyEqual引入的组(即两个比较相等的键)   落入不同的分区)

答案 1 :(得分:2)

&#34; 23.2.5无序关联容器&#34;规定:

  

如果a.size()== b.size(),两个无序容器a和b比较相等   并且,对于从中获得的每个等价物=密钥组[Ea1,Ea2]   a.equal_range(Ea1),存在等效密钥组[Eb1,Eb2)   从b.equal_range(Ea1)获得,使得距离(Ea1,Ea2)==   距离(Eb1,Eb2)和is_permutation(Ea1,Ea2,Eb1)返回true。

剥离它,这一切都归结为按std::is_permutation()定义的无序容器的相等性。

重要的是,这引用了std::is_permutation()的三个参数形式,而不是四个参数形式!

换句话说,对于无序容器的内容而言,整个纸牌屋最终被缩减为默认operator==,而不是容器的官方比较功能。

我对此有所了解。