如何根据作为STL容器的模板参数模拟所选成员函数的部分特化? [英] How to simulate a partial specialization of selected member functions based on a template parameter that is an STL container?
问题描述
我正在使用一个使用STL容器作为模板参数的类。不是所有的容器都提供相同的方法,所以我想知道如何基于所使用的容器专门化具体的方法。
I am working with a class that uses STL containers as a template parameter. Not all containers provide the same methods though, so I am trying to figure out how I can specialise specific methods based on the container used.
示例:
template<typename container>
class A
{
private:
container m_container;
public:
void foo(); // does something container specific
// more generic methods that work with any container
};
以下代码不会编译说无法匹配方法专用化,但这是大约我想要实现的:
The following code doexsn't compile saying "Can't match method specialisation", but this is approximately what I want to achieve:
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编译器...
I have to support a number of compilers including MSVC2010, gcc C++99, an old Solaris compiler...
我发现是实现外部方法,做任何 foo
应该做和重载它们为不同的容器类型。但是我不想在全球范围内公开这些函数,有没有办法通过专门化来做呢?
The only way around this fiasco that I found was to implement external methods that do whatever foo
is supposed to do and overload them for the different container types. But I don't want to expose those functions globally, is there a way to do it through specialisations?
特殊情况下,不可能外包他们是构造函数。 ..
Special case where it's not possible to outsource them is constructor specialisations...
推荐答案
选项#1
使用 -dispatch :
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
};
部分专用于具有静态成员函数的单独类:
Partially-specialize a separate class with a static member function:
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
};
从部分专用类导出 成语:
Derive from a partially specialized class + CRTP idiom:
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 建议的继承层次结构 / a>在注释中:
Use an inversed inheritance hierarchy as proposed by David Rodríguez - dribeas in the comments:
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
}
};
这篇关于如何根据作为STL容器的模板参数模拟所选成员函数的部分特化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!