3 回答

TA貢獻1802條經驗 獲得超10個贊
明確允許并鼓勵您向名稱空間* 添加特殊化std。添加哈希函數的正確方法(基本上是唯一方法)是:
namespace std {
template <> struct hash<Foo>
{
size_t operator()(const Foo & x) const
{
/* your code here, e.g. "return hash<int>()(x.value);" */
}
};
}
(您可能考慮支持其他受歡迎的專業有std::less,std::equal_to和std::swap。)
*)我想,只要其中一種涉及類型是用戶定義的即可。

TA貢獻1719條經驗 獲得超6個贊
我的賭注將放在unordered_map / unorder_set / ...類的Hash模板參數上:
#include <unordered_set>
#include <functional>
struct X
{
int x, y;
std::size_t gethash() const { return (x*39)^y; }
};
typedef std::unordered_set<X, std::size_t(*)(const X&)> Xunset;
typedef std::unordered_set<X, std::function<std::size_t(const X&)> > Xunset2;
int main()
{
auto hashX = [](const X&x) { return x.gethash(); };
Xunset my_set (0, hashX);
Xunset2 my_set2(0, hashX); // if you prefer a more flexible set typedef
}
當然
hashX可能也是一個全局靜態函數
在第二種情況下,您可以通過
老式仿函數對象(struct Xhasher { size_t operator(const X&) const; };)
std::hash<X>()
任何滿足簽名的綁定表達式-

TA貢獻1775條經驗 獲得超11個贊
涵蓋了1)和3)。
2)即使g ++和VC10聲明std::hash<T>::operator()具有不同的簽名,兩種庫實現也符合標準。
該標準未指定的成員std::hash<T>。它只是說每個這樣的專業化必須滿足的第二個模板參數等的相同“散列”要求std::unordered_set。即:
哈希類型H是一個函數對象,至少具有一個參數類型Key。
H 是可復制構造的。
H 是可破壞的。
如果h是類型H或的表達式const H,并且k是可以轉換為(可能const)的類型的表達式Key,則h(k)是類型為的有效表達式size_t。
如果h是類型H或的表達式const H,并且u是類型的左值Key,則h(u)是一個有效的表達式,其類型size_t不會修改u。
- 3 回答
- 0 關注
- 853 瀏覽
添加回答
舉報