2

型消去デザイン パターンを使用して、テンプレート クラスの 1 つにテンプレートに依存しないインターフェイスを公開しています。しかし、2 つのテンプレート化されたインスタンスを別のテンプレート定数パラメーター引数を持つ 3 番目のインスタンスに融合する、公開したいメソッドの 1 つが、違法なテンプレート仮想メソッドを必要とするように見えるという問題に遭遇しました。

これは私のコードです:

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

仮想テンプレートメンバーを必要としない、これを実装する別の方法はありますか?

編集: この「テンプレートに依存しないインターフェイス」の目的は、さまざまなテンプレート パラメーターを持つバー インスタンスのベクトルを関数に渡すことです。

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

編集:

上記のヒューズメソッドの代わりに印刷メソッドを使用した、より簡単な作業例を次に示します。これは、これがどのように機能するかを示しています。

http://codepad.org/8UbJguCR

4

1 に答える 1

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 インデックスのように、 でコードを書くのに役立つきれいなインターフェイスを用意してください。

タイプ erase にa を渡すと、コンポーネントbar<N>を無視して、タイプ erase the を入力します。これは非常に簡単です。bar<N>bar_raw

bar_raw必要に応じて yourを呼び出すことも、実装の詳細としてbar_any残して、すべてきれいbar_rawな でラップすることもできます。bar_any

于 2013-11-04T19:51:19.397 に答える