在 std::unordered_set
中使用自定义类型我不得不选择。
1) 执行==
我的类型和专业的运算符 std::hash
struct MyType {
int x;
bool operator==(const MyType& o) {
return this.x == o.x;
}
};
namespace std
{
template<>
struct hash<MyType> {
size_t operator()(const MyType& o) const {
return hash<int>()(o.x);
}
};
}
std::unordered_set<MyType> mySet;
或者2),提供仿函数类:
struct MyTypeHash {
size_t operator()(const MyType& o) const {
return std::hash<int>()(o.x);
}
};
struct MyTypeCompare {
bool operator()(const MyType& o1, const MyType& o2) const {
return o1.x == o2.x;
}
};
std::unordered_set<MyType, MyTypeHash, MyTypeCompare> mySet;
第二种方法让我为
std::unordered_set
的每个新实例选择新的行为。 ,而第一种方法作为类型本身的一部分的行为将始终相同。现在,如果我知道我只想要一个行为(我永远不会为
MyType
定义两个不同的比较器),那么首选哪种方法?这两者之间还有哪些不同之处?
最佳答案
将行为附加到类型允许类似的代码
template<template<class> Set,class T>
auto organizeWithSet(…);
/* elsewhere */ {
organizeWithSet<std::unordered_set,MyType>(…);
organizeWithSet<std::set,MyType>(…);
}
这显然不能传递自定义函数对象。
也就是说,可以定义
template<class T>
using MyUnorderedSet=std::unordered_set<T, MyTypeHash,MyTypeCompare>;
并将其用作模板模板参数,尽管它引入了另一个名称并且可能被认为不太可读。
否则,您必须考虑到您的
operator==
同时是 std::unordered_set
的默认值和 std::find
等;如果出于这些目的您想要的等价物有所不同,您可能需要命名比较器。另一方面,如果一个就足够了,C++20 甚至可以让你只用 =default
来定义它。 .
关于c++ - 具有覆盖运算符或外部仿函数的可散列类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59075409/