テンプレート テンプレート パラメータを使用する必要があります。
template<typename T, template <typename, typename> class Container>
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
class MyMultibyteString
{
Container<T, std::allocator<T>> buffer;
// ...
};
これにより、次のように記述できます。
MyMultibyteString<int, std::vector> mbs;
これはライブのコンパイル例です。上記を別の方法で書くと、次のようになります。
template<typename T,
template <typename, typename = std::allocator<T>> class Container>
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
class MyMultibyteString
{
Container<T> buffer; // <== No more need to specify the second argument here
// ...
};
そして、これが対応するlive exampleです。
注意しなければならない唯一のことは、テンプレート テンプレート パラメーター宣言の引数の数と型が、テンプレート引数として渡したい対応するクラス テンプレートの定義の引数の数と型と正確に一致する必要があることです。これらのパラメーターの一部にはデフォルト値がある可能性があります。
たとえば、クラス テンプレートstd::vector
は 2 つのテンプレート パラメーター(要素の型とアロケーターの型) を受け入れますが、2 番目のパラメーターには既定値がありますstd::allocator<T>
。このため、次のように書くことができませんでした。
template<typename T, template <typename> class Container>
// ^^^^^^^^
// Notice: just one template parameter declared!
class MyMultibyteString
{
Container<T> buffer;
// ...
};
// ...
MyMultibyteString<int, std::vector> mbs; // ERROR!
// ^^^^^^^^^^^
// The std::vector class template accepts *two*
// template parameters (even though the second
// one has a default argument)
std::set
これは、 と の両方をテンプレート テンプレート パラメータとして受け入れる単一のクラス テンプレートを作成できないことを意味します。これは、とはstd::vector
異なりstd::vector
、クラス テンプレートは3 つのテンプレート パラメータを受け入れるためです。std::set