2017-11-28 3 views
0

私は、以下に示すように、テンプレートテンプレートがどのように同様の機能を実装するかについて頭を悩ましています。別のテンプレート引数を受け入れるテンプレートテンプレートコレクション

2つのクラス(Java)を考えてみましょう。最初のクラスは、第2のテンプレート引数のオブジェクトのみがそれに格納することができることを指定することによって、packメソッドによって返さ収集制限されていますのは、言わせて、ために

abstract class ContainerPacker<T, Container extends Collection<T>> { 
    abstract Container pack(T t); 
} 

そして、このクラスの実装を、Integerタイプはその後になります

class IntegerContainerPacker extends ContainerPacker<Integer, List<Integer>> { 
    @Override 
    List<Integer> pack(Integer t) { 
     List<Integer> list = new ArrayList<>(t); 
     list.add(t); 
     return list; 
    } 
} 

今私はテンプレートテンプレートを使ってC++で同様のことをしたいと思います。

template <typename T, template <typename U> class Container> 
class ContainerPacker { 
    public: 
    virtual Container<T> pack(T) = 0; 
}; 

私もそれを実装するトラブルを抱えている:Containerは、テンプレートそのものであることに注目してください。以下のコードはコンパイルされません:

class IntegerVectorPacker : public ContainerPacker<int, std::vector> { 
    public: 
    std::vector<int> pack(int t) { 
     std::vector<int> v = std::vector<int>(); 
     v.push_back(t); 
     return v; 
    } 
}; 

エラーは以下のとおりです。

error: type/value mismatch at argument 2 in template parameter list for ‘template class Container> class ContainerPacker’ class IntegerVectorPacker : public ContainerPacker {

note: expected a template of type ‘template class Container’, got ‘template class std::vector’

私は答えを探してきたが、それも難しいのですがどのような質問を把握します聞く、質問する。テンプレートテンプレートは難しいです。

+1

2番目のエラーは、 'std :: vector 'というフルスペシャライゼーションを提供するのではなく、2番目のテンプレートパラメータとして 'std :: vector'を指定したことに関連しているようです。それは、テンプレートクラスを期待していたが、クラス名を指定したということです。 – Howard

答えて

1

あなたのコード内で

template <typename T, template <typename...> class Container> 

問題(?問題)で試してみてくださいはstd::vectorは(2:二つ目は、デフォルトの型を持つ)複数のテンプレート引数を受け取るテンプレートクラスであるということです。したがって一致しませんContainer

ゼロ以上のテンプレートを受けるようContainerを定義すると、(本当にstd::vector<int, std::allocator<int>>であること)std::vector<int>との一致を許可し、他のコンテナなければなりません。

- EDIT -

は、私はあなたがタグ付けこの質問のC++とC++ではない11(またはそれ以降)を持っていることを今参照してください。

typename...の提案は、バリデーションテンプレートが以前から利用できなかったため、C++ 11からのみ有効です。 C++ 98

あなたは

template <typename T, template <typename, typename> class Container> 

を書くことができますが、これは2つのパラメータのコンテナでのみ動作します。

- EDIT 2から

トピックの提案オフ。

あなたはContainerPackerためContainerTの順序を切り替えてTを変換するC++ 11以降(そう可変引数テンプレート)を使用することができた場合は可変長引数パックです。何かのように

template <template <typename...> class Container, typename ... Ts> 
class ContainerPacker { 
    public: 
    virtual Container<Ts...> pack(Ts...) = 0; 
}; 

これはずっと柔軟です。

+0

ああ、それは完璧です!私はそれが複数のテンプレート引数を持っていることに気づいたが、2番目のテンプレート引数はデフォルトになっているので、省略できると思った。とにかく、それは動作します、ありがとうございます( – Jezor

+1

)@Jezor - オフトピックの提案を追加しました(C++ 11以降を使用できる場合) – max66

+0

もう一度ありがとうございます(:私はC++ 11を使用しています。実装で他のテンプレート引数を指定する方法については疑問に思っていた – Jezor

関連する問題