我正在使用使用STL容器作为模板参数的类。尽管并非所有容器都提供相同的方法,所以我试图弄清楚如何根据所使用的容器来专门化特定的方法。
例子:
template<typename container>
class A
{
private:
container m_container;
public:
void foo(); // does something container specific
// more generic methods that work with any container
};
以下代码不会编译为“无法匹配方法专业化”,但这大约是我想要实现的:
template<typename T>
template<>
void A<std::vector<T> >::foo()
{
// vector specific implementation
}
template<typename T>
template<>
void A<std::map<T> >::foo()
{
// map specific implementation
}
我必须支持许多编译器,包括MSVC2010,gcc C ++ 99,旧的Solaris编译器...
我发现绕过这一惨败的唯一方法是实现外部方法,该方法可以执行foo
应做的事情,并针对不同的容器类型重载它们。但是我不想在全球范围内公开这些功能,有没有办法通过专业化来做到这一点?
无法外包的特殊情况是构造器专业化...
使用标记分派:
template <typename T>
struct tag {};
template <typename container>
class A
{
private:
container m_container;
template <typename T, typename Alloc>
void foo_spec(tag<std::vector<T, Alloc> >)
{
// vector specific implementation
}
template <typename K, typename V, typename C, typename Alloc>
void foo_spec(tag<std::map<K,V,C,Alloc> >)
{
// map specific implementation
}
public:
void foo()
{
foo_spec(tag<container>());
}
// more generic methods that work with any container
};
部分静态化具有静态成员函数的单独类:
template <typename T>
struct Impl;
template <typename T, typename Alloc>
struct Impl<std::vector<T, Alloc> >
{
static void foo_spec()
{
// vector specific implementation
}
};
template <typename K, typename V, typename C, typename Alloc>
struct Impl<std::map<K,V,C,Alloc> >
{
static void foo_spec()
{
// map specific implementation
}
};
template <typename container>
class A
{
private:
container m_container;
public:
void foo()
{
Impl<container>::foo_spec();
}
// more generic methods that work with any container
};
从部分专业的类+ CRTP习惯派生:
template <typename container>
class A;
template <typename CRTP>
struct Base;
template <typename T, typename Alloc>
struct Base<A<std::vector<T, Alloc> > >
{
void foo()
{
// vector specific implementation
A<std::vector<T, Alloc> >* that = static_cast<A<std::vector<T, Alloc> >*>(this);
}
};
template <typename K, typename V, typename C, typename Alloc>
struct Base<A<std::map<K,V,C,Alloc> > >
{
void foo()
{
// map specific implementation
A<std::map<K,V,C,Alloc> >* that = static_cast<A<std::map<K,V,C,Alloc> >*>(this);
}
};
template <typename container>
class A : public Base<A<container> >
{
friend struct Base<A<container> >;
private:
container m_container;
public:
// more generic methods that work with any container
};
使用DavidRodríguez-dribeas在评论中建议的反向继承层次结构:
template <typename container>
class Base
{
private:
container m_container;
public:
// more generic methods that work with any container
};
template <typename container>
class A;
template <typename T, typename Alloc>
class A<std::vector<T, Alloc> > : public Base<std::vector<T, Alloc> >
{
public:
void foo()
{
// vector specific implementation
}
};
template <typename K, typename V, typename C, typename Alloc>
class A<std::map<K,V,C,Alloc> > : public Base<std::map<K,V,C,Alloc> >
{
public:
void foo()
{
// map specific implementation
}
};
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句