2013-04-07 82 views
0

我有一個簡單的哈希表的模板,模板類多重定義

template <class K, class V, long H(K)> 
class HashTableAbs{/* .... */} 
//where K is key type, V is value type, H gives hash code for K value 

和簡單的繼承類

template <class K, class V, long H(K)> 
class HashTable:public HashTableAbs<K, V, H> {}; 

,我想專攻此模板的字符串,用我的默認哈希函數

template <class V> 
class HashTable<std::string, V, strSimpleHash>:public HashTableAbs<std::string, V, strSimpleHash> {}; 
//where strSimpleHash is long strSimpleHash(std::string) 

但是當我試圖編譯這個編譯器寫這個

test.o: In function `strSimpleHash(std::string)': 
test.cpp:(.text+0x0): multiple definition of `strSimpleHash(std::string)' 
/tmp/main-i7yPhc.o:main.cc:(.text+0x0): first defined here 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

(測試包括其中哈希表定義hashtable.h) strSimpleHash僅被定義在hashtable.h

有沒有出路? PS抱歉我寫錯了。英語不是我的母語

+0

您是否在模板特化之前或之後定義了strSimpleHash?它需要在之前。 – Dave 2013-04-07 18:42:24

+0

我將它定義模板和模板特 – 2013-04-07 18:44:55

+0

之前,請表現出更多,代碼,尤其是在其中定義'strSimpleHash',更完整的答案的一部分。 – Synxis 2013-04-07 18:46:26

回答

3

此錯誤是不是真的涉及到的模板。它是一個函數的多重定義。我想你已經在頭文件中定義了strSimpleHash而沒有使用inline(你沒有在你定義這個函數的地方添加代碼)。

您在您的評論中問道,一種使用HashTable類似如下:

HashTable<std::string, int> // (ie, without passing the 3rd argument) 

這是不能直接成爲可能。 Althought你可以指定一個模板參數的默認值(而不是在一個專門化),例如:

template<int n = 0> struct dummy {}; 
dummy<> obj; 

你的情況,你不能這樣做,因爲你的模板,一般情況下不接受的唯一功能類型爲long(std::string)。 但是,可以通過爲每種可能的類型分配默認函數來解決此問題。需要注意的是,你應該使用指針到函數,代碼更清晰一點:

// A C++03-style template typedef 
template<typename K> 
struct HashFunc 
{ 
    typedef long (*type)(K); 
}; 

// The default value. Defined only for some cases, 
// compile error for not handled cases 
template<typename K> 
struct DefaultHash; 

template<> 
struct DefaultHash<std::string> 
{ 
    // Static constant pointer-to-function, pointing to the hash func. 
    static constexpr HashFunc<std::string>::type func = &strSimpleHash; 
}; 

// The HashTable class 
template <class K, class V, typename HashFunc<K>::type H = DefaultHash<K>::func> 
class HashTable 
{ 
}; 

template <class V> 
class HashTable<std::string, V, strSimpleHash> 
{ 
}; 

然後你可以使用它作爲你想,省略了第三個模板參數。請注意,此代碼爲compiles on gcc,但是not on clang(實際上,我不確定哪個編譯器是正確的......)

+0

太棒了!我將內聯添加到strSimpleHash並編譯。但是,當我試圖定義HashTable *表,編譯器寫入:test.cpp:126:17:錯誤:類模板太少的模板參數'HashTable' void printTable(HashTable * table) – 2013-04-07 18:52:07

+0

太棒了!對於你在註釋中的內容,你忘了傳遞函數:'HashTable * table;'。 – Synxis 2013-04-07 18:54:28

+0

我可以專注我的模板,使這個(哈希表<的std :: string,int>的*表)是否有效? – 2013-04-07 18:59:02