我想部分专门化一个现有的模板,我无法改变(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();
}
};
} }
Run Code Online (Sandbox Code Playgroud)
但是这种专门化只与实际的派生类不匹配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();
}
};
} }
Run Code Online (Sandbox Code Playgroud)
......但是,这并不工作,因为编译器不能告诉大家,enable_if<condition, Derived>::type是Derived.如果我可以更改std::tr1::hash,我只需添加另一个虚拟模板参数boost::enable_if,如enable_if文档所建议的那样,但这显然不是一个很好的解决方案.有没有解决这个问题的方法?我是否必须在每个unordered_set或 …
考虑类模板,可以使用类型特征和虚拟启用模板参数为某些类型的组提供模板特化.我早些时候已经问过了.
现在,我对函数模板需要相同的东西:即,我有一个模板函数,并希望对一组类型进行特化,例如,所有类型都是类的子类型X.我可以用这样的类型特征来表达这个:
std::enable_if<std::is_base_of<X, T>::value>::type
Run Code Online (Sandbox Code Playgroud)
我想过这样做:
template <typename T, typename ENABLE = void>
void foo(){
//Do something
}
template <typename T>
void foo<T,std::enable_if<std::is_base_of<A, T>::value>::type>(){
//Do something different
}
Run Code Online (Sandbox Code Playgroud)
但是,这不起作用,因为功能模板不允许部分特化.那么怎么做呢?也许类型为trait的默认参数为type?但是代码怎么样呢?