【问题标题】:Can not compare std::unorded_set with custom KeyEqual无法将 std::unorded_set 与自定义 KeyEqual 进行比较
【发布时间】:2016-07-10 03:06:44
【问题描述】:

以下程序无法编译。但是如果我不注释掉operator==,它就会编译。为什么在我已经提供FooEqual 的情况下仍然需要operator==

#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;
}

【问题讨论】:

  • 必须是实现中的错误...除非规范说KeqEqual 仅用于插入/查找,并且std::unordered_set::operator== 根据各个元素是否相等来检查两个集合是否相等比较相等?这里可能需要 C++ 语言律师。

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


【解决方案1】:

根据http://en.cppreference.com/w/cpp/container/unordered_set/operator_cmp,您实际上确实需要operator== 进行比较(我现在无法访问标准 - 我会在明天的某个时候尝试更新具体的报价):

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

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

【讨论】:

    【解决方案2】:

    “23.2.5 无序关联容器”状态:

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

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

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

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

    这是我读到的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-18
      • 1970-01-01
      • 2015-10-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多