Ответ 1
Вы должны использовать параметры шаблона шаблона:
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
// ...
};
И вот соответствующий живой пример.
Единственное, на что вы должны обратить внимание, это то, что количество и тип аргументов в объявлении параметра шаблона шаблона должны точно соответствовать количеству и типу аргументов в определении соответствующего шаблона класса, который вы хотите передать в качестве шаблона аргумент, независимо от того, что некоторые из этих параметров могут иметь значения по умолчанию.
Например, шаблон шаблона std::vector
принимает два параметра шаблона (тип элемента и тип распределителя), хотя второй имеет значение по умолчанию 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
, шаблон класса std::set
принимает три параметра шаблона.