基本クラスとすべての派生クラスに対して変更できない既存のテンプレート(std::tr1::hash
)を部分的に特殊化したいとします。その理由は、私は多様性のために奇妙に繰り返されるテンプレートパターンを使用しており、ハッシュ関数はCRTP基本クラスに実装されているからです。私は部分的にしかCRTP基本クラス用に特化したい場合は、それは簡単です、私は書くことができます:すべての派生型のクラステンプレートを部分的に特殊化する方法は?
namespace std { namespace tr1 {
template <typename Derived>
struct hash<CRTPBase<Derived> >
{
size_t operator()(const CRTPBase<Derived> & base) const
{
return base.hash();
}
};
} }
をしかし、この専門分野は、実際の派生クラスだけCRTPBase<Derived>
と一致していません。私が欲しいのは、CRTPBase<Derived>
から派生した場合に限り、Derived
の部分専門化を書く方法です。私の擬似コードは、
namespace std { namespace tr1 {
template <typename Derived>
struct hash<typename boost::enable_if<std::tr1::is_base_of<CRTPBase<Derived>, Derived>,
Derived>::type>
{
size_t operator()(const CRTPBase<Derived> & base) const
{
return base.hash();
}
};
} }
です...しかし、コンパイラはenable_if<condition, Derived>::type
がDerived
であることを伝えることができないので、それは動作しません。 std::tr1::hash
を変更できる場合は、enable_if
のドキュメントで推奨されているように、別のダミーテンプレートパラメータをboost::enable_if
に追加するだけですが、それは非常に良い解決策ではありません。この問題を回避する方法はありますか?派生クラスごとにunordered_set
またはunordered_map
のカスタムハッシュテンプレートを指定するか、hash
を完全に特化する必要がありますか?
いいね、ありがとう。 – Doug