簡體   English   中英

將哈希函數定義為結構的一部分

[英]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_setstd命名空間中定義。 它使用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);
  }
};

Fooun_setun_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM