2011-10-01 72 views
12

我想定義一個適用於給定基類的所有子類的C++模板特化。這可能嗎?所有小類的模板特化

特別是,我想這樣做STL的散列<>。哈希<>被定義爲一個空的參數化模板,爲特定類型的家庭專業化的:

template<class _Key> 
    struct hash { }; 

template<> 
    struct hash<char> 
    { 
    size_t 
    operator()(char __x) const 
    { return __x; } 
    }; 

template<> 
    struct hash<int> 
    { 
    size_t 
    operator()(int __x) const 
    { return __x; } 
    }; 
... 

我想定義是這樣的:

template<class Base> 
    struct hash { 
    size_t operator()(const Base& b) const { 
     return b.my_hash(); 
    } 
    }; 

class Sub : public Base { 
    public: 
    size_t my_hash() const { ... } 
}; 

,並能夠使用它像這個:

hash_multiset<Sub> set_of_sub; 
set_of_sub.insert(sub); 

但是,我的哈希模板與STL的通用模板衝突。有沒有一種方法(可能使用特徵)來定義適用於給定基類的所有子類的模板特化(不修改STL定義)?

注意,我知道我可以在每次需要這個哈希專業化一些額外的模板參數做到這一點,但我想避免這種可能的話:

template<> 
    struct hash<Base> { 
    size_t operator()(const Base& b) const { 
     return b.my_hash(); 
    } 
    }; 

.... 

// similar specialization of equal_to is needed here... I'm glossing over that... 
hash_multiset<Sub, hash<Base>, equal_to<Base> > set_of_sub; 
set_of_sub.insert(sub); 
+0

如果其衝突爲什麼不使用命名空間? – Arunmu

+1

http://stackoverflow.com/questions/1032973/how-to-partially-specialize-a-class-template-for-all-derived-types –

+0

可能的重複...其中解決方案是命名所有派生類以類似的方式,這不是很滿意。 – jpalecek

回答

1

的解決方案是使用SFINAE決定是否允許根據類繼承結構進行專門化。在Boost中,您可以使用enable_ifis_base_of來執行此操作。

+0

恐怕在這種情況下你不能使用'enable_if'。 – jpalecek

+0

jpalecek:爲什麼不呢?順便說一句,如果boost是這裏的答案,它可能無法幫助我,因爲我的工作場所限制了我們可以使用的庫,boost :: enable_if不是規定子集的一部分。 –

+0

然後你可能不得不推出自己的產品,但是你應該能夠通過使用SFINAE來獲得你想要的東西。 – KayEss

0

這是最好的,我可以這樣做:

template<> 
    struct hash<Sub> : hash<Base> { 
    }; 

我有點擔心,我沒有做operator()虛擬的,但。

相關問題