2014-10-27 28 views
0

幾個問題/問題:C++重寫哈希<T>對於T的派生類

  1. 下面的代碼沒有編制(見下面的評論)
  2. 我將不得不重寫了酒吧散列函數和如果我想讓他們返回id()作爲它們的哈希值,那麼也是Baz?
#include <functional> 

class Foo 
{ 
public: 
    Foo(short id); 
    short id() const; 
private: 
    const short id_; 
}; 

class Bar : public Foo {}; 

class Baz : public Foo {}; 

Foo::Foo(short id) : 
id_(id) 
{} 

short Foo::id() const 
{ 
    return id_; 
} 

namespace std 
{ 
    template <> struct hash<Foo> //hash is not a class template 
    { //explicit specialization of non-template std::hash 
    size_t operator()(const Foo& foo) const 
    { 
     return hash<short>()(foo.id()); //std::hash is not a template 
    } 
    }; 
} 
+0

'Foo :: id()'需要聲明爲'const'。 – 2014-10-27 01:26:01

+0

這裏沒有重要的事情發生。 – 2014-10-27 01:27:06

+0

你一定要專門爲所有類型的'std :: hash'專門化,它應該有特殊的行爲。 – Deduplicator 2014-10-27 01:28:06

回答

1

的問題是const引用被傳遞給hash::operator()Foo::id()未聲明const。這樣可以防止您在 Foo的實例上調用id()。爲了解決這個問題只需要聲明的功能const像這樣

class Foo 
{ 
public: 
    short id() const; 
}; 

如果要定義的std::hash一個實例,並通過派生類爲模板參數,你會需要提供爲每一個一體的專業化。如果您只是將派生類的實例傳遞給std::hash<Foo>,則不需要爲它們提供專門化。

還要確保您使用的是C++ 11編譯器(如果需要,啓用C++ 11模式),並且包含Kerrek在註釋中提到的<functional>標頭。

+0

@Captain Obvlious我也這麼做,仍然沒有編譯。 – 2014-10-27 01:40:01

+0

@Deduplicator「未轉換」是什麼意思?你是說我必須寫std :: hash 和std :: hash 呢? – 2014-10-27 01:43:35

+0

@AgrimPathak我根據重複數據刪除者的評論更新了我的答案,以澄清我所指的內容。 – 2014-10-27 01:44:11