所有子类的模板专门化 < >我想定义一个C++模板特化,它适用于给定基类的所有子类。这可能吗
特别是,我想为STL的散列做这个。散列定义为空的参数化模板,以及特定类型的一系列专门化:所有子类的模板专门化 < >我想定义一个C++模板特化,它适用于给定基类的所有子类。这可能吗,c++,templates,subclass,template-specialization,C++,Templates,Subclass,Template Specialization,特别是,我想为STL的散列做这个。散列定义为空的参数化模板,以及特定类型的一系列专门化: template<class _Key> struct hash { }; template<> struct hash<char> { size_t operator()(char __x) const { return __x; } }; template<> struct hash<int>
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; }
};
...
模板
结构散列{};
模板
结构散列
{
尺寸
运算符()
{return\uuux;}
};
模板
结构散列
{
尺寸
运算符()
{return\uuux;}
};
...
我想定义如下:
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);
模板
结构散列{
大小\u t运算符()(常数基和b)常数{
返回b.my_hash();
}
};
组别分组:公共基地{
公众:
大小\u t我的哈希()常量{…}
};
并且能够像这样使用它:
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);
hash\u\u子集合的多集合;
设置子项插入(子项)的子项;
但是,我的哈希模板与STL中的通用模板冲突。是否有一种方法(可能使用traits)来定义适用于给定基类的所有子类的模板专门化(而不修改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);
模板
结构散列{
大小\u t运算符()(常数基和b)常数{
返回b.my_hash();
}
};
....
//这里需要类似于的专门化。。。我在掩饰。。。
子集合的哈希集合;
设置子项插入(子项)的子项;
解决方案是使用SFINAE根据类继承结构决定是否允许您的专业化。在Boost中,如果和是
的基础,则可以使用启用来实现此功能
这是我能做的最好的事情:
template<>
struct hash<Sub> : hash<Base> {
};
模板
结构哈希:哈希{
};
我有点担心,我不必使操作符()
虚拟化。因为C++11可以与标准库一起使用来解决问题。如果冲突,为什么不使用名称空间?可能是。。。解决方法是以类似的方式命名所有派生类,这不是很令人满意。在这种情况下,恐怕您不能使用enable\u if
。jpalecek:为什么不?顺便说一句,如果boost是这里的答案,它可能对我没有任何帮助,因为我的工作场所限制了我们可以使用的库,而boost::enable_if不是指定子集的一部分。那么你可能需要自己的,但是通过使用SFINAE,你应该能够得到你想要的东西。这个回答实际上并没有回答OP的问题。