如何基于作为STL容器的模板参数来模拟所选成员函数的部分特化?

Ser*_* L. 7 c++ templates template-specialization

我正在使用一个使用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
};
Run Code Online (Sandbox Code Playgroud)

下面的代码不会编译说"无法匹配方法专门化",但这大概是我想要实现的:

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
}
Run Code Online (Sandbox Code Playgroud)

我必须支持许多编译器,包括MSVC2010,gcc C++ 99,一个旧的Solaris编译器......

我发现这种惨败的唯一方法是实现外部方法,这些方法可以做任何foo应该做的事情,并为不同的容器类型重载它们.但我不想在全球范围内公开这些功能,有没有办法通过专业化来实现?

不可能外包它们的特殊情况是构造函数专门化......

Pio*_*cki 10

选项1

使用标签调度:

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
};
Run Code Online (Sandbox Code Playgroud)

演示1

选项#2

使用静态成员函数部分专门化一个单独的类:

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
};
Run Code Online (Sandbox Code Playgroud)

演示2

选项#3

派生自部分专业的类+ 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
};
Run Code Online (Sandbox Code Playgroud)

演示3

选项#4

使用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
    }
};
Run Code Online (Sandbox Code Playgroud)

演示4