C ++:类型擦除虚拟模板解决方法

时间:2013-11-04 18:38:48

标签: c++ templates type-erasure

我使用类型擦除设计模式为我的一个模板类公开一个独立于模板的接口。但是,我遇到的问题是,我希望公开的方法之一,它将两个模板化实例融合到具有不同模板常量参数参数的第三个实例中,似乎需要模板虚拟方法,这是非法的。

这是我的代码:

#include <stdlib.h>

template<size_t N>
class bar
{
    template<size_t M>
    bar<M+N> fuse(const bar<M>& rhs) { return bar<M+N>(); }
};

class bar_any_N 
{
private:
    class abstract_base
    {
        virtual bar_any_N fuse(const abstract_base* rhs) = 0;

        template<size_t M>
        virtual bar_any_N fuse_accept(const bar<M>& lhs) = 0;
    };

    template<size_t N>
    class wrapper : public abstract_base
    {
    private:
        bar<N> m_bar;
    public:
        wrapper(const bar<N>& the_bar) : m_bar(the_bar) { }

        bar_any_N fuse(const abstract_base* rhs) { return rhs->fuse_accept(*this); }

        template<size_t M>
        bar_any_N fuse_accept(const bar<M>& lhs) { return lhs.m_bar.fuse(this->m_bar) }
    };

    abstract_base* m_ptr;
public:
    template<size_t N> 
    bar_any_N(const bar<N>& the_bar) { m_ptr = new wrapper<N>(the_bar); }

};

int main()
{
    bar<1> b1;
    bar<2> b2;
    bar_any_N b1_erased(b1);
    bar_any_N b2_erased(b2);

    bar_any_N b3 = b1_erased.fuse(b2_erased);

    return 0;
}

有没有其他方法可以实现这个不需要虚拟模板成员的方法?

编辑:这个'模板独立接口'的目的是将带有不同模板参数的bar实例向量传递给函数:

std::vector< bar_any_N > vec; 
vec.push_back(bar<2>()); 
vec.push_back(bar<5>()); 
foo_func(vec); 

编辑:

这是一个更简单的工作示例,使用打印方法而不是上面的保险丝方法,显示我将如何工作:

http://codepad.org/8UbJguCR

1 个答案:

答案 0 :(得分:2)

进行内部类型擦除。

struct bar_raw
{
  std::size_t N;
  explicit bar_raw( std::size_t n ):N(n) {}
  bar_raw fuse( const bar_raw& rhs ) { return bar_raw(N+rhs.N); }
};
template<size_t N>
struct bar: bar_raw
{
  bar():bar_raw(N) {}
  template<size_t M>
  bar<M+N> fuse(const bar<M>& rhs) { return bar<M+N>(); }
};

将所有州保持在bar_raw。有一个漂亮的界面,可以帮助在bar<N>中编写代码,就像n-ary索引一样。

当传递bar<N>进行类型擦除时,忽略bar<N>组件并键入擦除bar_raw,这非常简单。

如果您愿意,可以致电bar_raw bar_any,或者将bar_raw作为实施细节,并将其包装在bar_any中。