无法将 std::unorded_set 与自定义 KeyEqual 进行比较
Can not compare std::unorded_set with custom KeyEqual
以下程序无法编译。但是如果我不注释掉 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;
}
根据 http://en.cppreference.com/w/cpp/container/unordered_set/operator_cmp,您实际上确实需要 operator==
进行比较(我现在无法访问该标准 - 我将尝试在明天某个时候更新具体报价):
The behavior is undefined if Key is not EqualityComparable.
The behavior is also undefined if Hash and KeyEqual do not have the
same behavior on lhs and rhs or if the equality comparison operator
for Key is not a refinement of the partition into equivalent-key
groups introduced by KeyEqual (that is, if two keys that compare equal
fall into different partitions)
“23.2.5 无序关联容器”指出:
Two unordered containers a and b compare equal if a.size() == b.size()
and, for every equivalent=key group [Ea1,Ea2) obtained from
a.equal_range(Ea1), there exists an equivalent-key group [Eb1,Eb2)
obtained from b.equal_range(Ea1), such that distance(Ea1, Ea2) ==
distance(Eb1, Eb2) and is_permutation(Ea1, Ea2, Eb1) returns true.
剥离它,这一切都归结为根据 std::is_permutation()
.
定义的无序容器的相等性
重要的是,它引用了 std::is_permutation
() 的三参数形式,而不是四参数形式!
换句话说,整个纸牌屋最终被缩减为默认的operator==
,用于无序容器的内容,而不是容器的官方比较功能。
这是我的读物。
以下程序无法编译。但是如果我不注释掉 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;
}
根据 http://en.cppreference.com/w/cpp/container/unordered_set/operator_cmp,您实际上确实需要 operator==
进行比较(我现在无法访问该标准 - 我将尝试在明天某个时候更新具体报价):
The behavior is undefined if Key is not EqualityComparable.
The behavior is also undefined if Hash and KeyEqual do not have the same behavior on lhs and rhs or if the equality comparison operator for Key is not a refinement of the partition into equivalent-key groups introduced by KeyEqual (that is, if two keys that compare equal fall into different partitions)
“23.2.5 无序关联容器”指出:
Two unordered containers a and b compare equal if a.size() == b.size() and, for every equivalent=key group [Ea1,Ea2) obtained from a.equal_range(Ea1), there exists an equivalent-key group [Eb1,Eb2) obtained from b.equal_range(Ea1), such that distance(Ea1, Ea2) == distance(Eb1, Eb2) and is_permutation(Ea1, Ea2, Eb1) returns true.
剥离它,这一切都归结为根据 std::is_permutation()
.
重要的是,它引用了 std::is_permutation
() 的三参数形式,而不是四参数形式!
换句话说,整个纸牌屋最终被缩减为默认的operator==
,用于无序容器的内容,而不是容器的官方比较功能。
这是我的读物。