[英]Defining hash function as part of a struct
我知道可以通過定義一個單獨的哈希函數struct來為struct X
定義哈希函數:
struct hash_X {
size_t operator()(const X &x) const {}
bool operator()(const X &a, const X &b) const {}
};
int main() {
unordered_set<X, hash_X, hash_X> s;
}
但我正在尋找類似operator<
東西,它可以附加到struct X
本身,例如使用set
:
struct X {
bool operator<(const X &other) const {}
};
int main() {
set<X> s;
}
最終目標是這樣的:
struct X {
size_t operator()(void) const {}
bool operator()(const X &other) const {}
};
int main() {
unordered_set<X> s;
}
這在C ++中是否可行?
std::unordered_set
在std
命名空間中定義。 它使用std::hash
結構來散列許多不同的類型。 如果您希望能夠使用std::unordered_set<X>
(不向聲明添加太多信息),則必須創建std::hash
模板的另一個重載,以使其對您的結構進行哈希處理 。
您應該能夠通過執行以下操作來使其正常工作:
# include <unordered_set>
struct X {
size_t operator()(void) const {}
bool operator()(const X &other) const {}
};
namespace std {
template<>
struct hash<X> {
inline size_t operator()(const X& x) const {
// size_t value = your hash computations over x
return value;
}
};
}
int main() {
std::unordered_set<X> s;
}
Andalso,您必須為std::equal_to
提供重載,或者為您的結構提供比較運算符( operator==()
)。 您應該添加以下內容之一:
struct X {
...
inline bool operator==(const X& other) const {
// bool comparison = result of comparing 'this' to 'other'
return comparison;
}
};
要么:
template <>
struct equal_to<X> {
inline bool operator()(const X& a, const X& b) const {
// bool comparison = result of comparing 'a' to 'b'
return comparison;
}
};
沒有哈希運算符,但您可以隱藏X
內的hash
結構:
struct X
{
std::string name;
struct hash
{
auto operator()( const X& x ) const
{ return std::hash< std::string >()( x.name ); }
};
};
你甚至可以把它變成朋友,私name
,等等。
namespace hashing {
template<class T>
std::size_t hash(T const&t)->
std::result_of_t<std::hash<T>(T const&)>
{
return std::hash<T>{}(t);
}
struch hasher {
template<class T>
std::size_t operator()(T const&t)const{
return hash(t);
}
};
}
以上是一些設置基於adl的hash
系統的樣板。
template<class T>
using un_set=std::unordered_set<T,hashing::hasher>;
template<class K, class V>
using un_map=std::unordered_map<K,V,hashing::hasher>;
現在創建兩個容器別名,您不必指定哈希。
要添加新的hashable:
struct Foo {
std::string s;
friend size_t hash(Foo const&f){
return hashing::hasher{}(s);
}
};
和Foo
在un_set
和un_map
。
我將std
容器和元組的支持添加到hashing
命名空間(覆蓋它們的函數hash
),並且神奇地這些也將起作用。
我建議考慮一個更通用的哈希類。 您可以為此類定義您可能需要的所有常見哈希操作操作:
struct ghash {
// all the values and operations you need here
};
然后,在您想要計算哈希的任何類中,您可以定義轉換運算符
struct X {
operator ghash () { // conversion operator
ghash rh;
// compute the hash
return rh;
}
};
然后,您可以輕松計算哈希值:
X x;
ghash hx = x; // convert x to a hash
hx = (ghash)x; // or if you prefer to make it visible
這樣可以更容易地擴展哈希結構的使用,而無需重新構建將來可能需要哈希的任何其他結構X,Y,Z的共同點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.