Я хочу частично специализировать существующий шаблон, который я не могу изменить (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>
. То, что я хочу, - это способ написания частичной специализации для Derived
тогда и только тогда, когда он происходит от CRTPBase<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
, я бы добавил еще один параметр шаблона манекена, чтобы использовать boost::enable_if
, как рекомендовано в документации enable_if
, но это, очевидно, не очень хорошее решение. Есть ли способ обойти эту проблему? Должен ли я указывать настраиваемый хэш-шаблон на каждом unordered_set
или unordered_map
Я создаю или полностью специализируюсь для hash
для каждого производного класса?
Выглядит хорошо, спасибо. – Doug