如何根据作为STL容器的模板参数模拟所选成员函数的部分特化? [英] How to simulate a partial specialization of selected member functions based on a template parameter that is an STL container?

查看:149
本文介绍了如何根据作为STL容器的模板参数模拟所选成员函数的部分特化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个使用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
};

DEMO 1

部分专用于具有静态成员函数的单独类:

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
};

DEMO 2

从部分专用类导出 成语:

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
};

DEMO 3

使用 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
    }
};

DEMO 4

这篇关于如何根据作为STL容器的模板参数模拟所选成员函数的部分特化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆