2011-10-01 7 views
12

与えられた基本クラスのすべてのサブクラスに適用されるC++テンプレートの特殊化を定義したいと思います。これは可能ですか?すべてのサブクラスのテンプレートの特殊化

特に、STLのハッシュ<>に対してこれを実行したいと思います。 <をハッシュ>が空のパラメータ化テンプレート、および特定のタイプのための専門の家族のように定義されます。

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 { ... } 
}; 

と同じようにそれを使用することができる:私はこのような何かを定義したいと思います

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; } 
    }; 
... 

これは、

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 :: enable_ifが指定されたサブセットの一部ではないので、boostはここでの答えです。 –

+0

あなた自身をロールバックする必要があるかもしれませんが、あなたはSFINAEを使ってあなたが望むように動作するものを手に入れることができます。 – KayEss

0

これは私が何ができる最高だった:

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

私はしかし、operator()仮想作るために持っていなかったことを少し心配です。

関連する問題