スポンサーリンク

可変長テンプレートとテンプレートテンプレートパラメータ

まず、私はこれがモダンな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;

}

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: