スポンサーリンク
まず、私はこれがモダンなC++の標準機能なのかは知らない。ただ、VC++2017で以下のようにやって動いた、という話。
例えば以下はエラー。
template< class Container, class Type > struct MyVector { Container<Type> o; };
int main() { MyVector<std::vector, int> mv; mv.o.push_back(1); }
あるクラスに、コンテナとその内容の型を別々に渡したいときは、以下のようにする。
template< class Type , template<class, class ___ALLCATOR = std::allocator<Type> > class Container > struct MyVector { Container<Type> o; };
int main() { MyVector<int, std::vector> mv; mv.o.push_back(1); }
ここで、template<class,class>は相手がvectorならよいが、unordered_mapなどを入れると互換性がないといわれる。
template< class Type, template<class, class ___ALLCATOR = std::allocator<Type> > class Container > struct MyVector { Container<Type> o; };
int main() { MyVector<int, std::unordered_map> mv; mv.o.push_back(1); }
クラス テンプレート 'std::unordered_map' 用テンプレート パラメーター リストがテンプレート パラメーター 'Container' 用テンプレート パラメーター リストと一致しません。
そこで、テンプレートテンプレートパラメータのほうのパラメータリストをパックする
template< template<class ...Args> class Container, class Type> struct MyVector { Container<Type> o; };
int main() { MyVector<std::vector,int> mv; mv.o.push_back(1); }
テンプレートテンプレートパラメータをパックできるので、コンテナに与える型もパックしてやると、色々なコンテナに対応したテンプレートクラスを作成できる。
template< template<class ...Args> class Container, class ...Type> struct MyVector { Container<Type...> o; };
int main() { MyVector< std::unordered_map, int, float> cm; MyVector< std::vector, float> cv; cm.o[100] = 50.3f; cv.o.push_back(30.0f); std::cout << "map " << cm.o[100] << std::endl; std::cout << "vec " << cv.o[0] << std::endl; int i; std::cin >> i; }