Вы должны использовать параметры шаблона шаблона:
template<typename T, template <typename, typename> class Container>
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
class MyMultibyteString
{
Container<T, std::allocator<T>> buffer;
// ...
};
Это позволит вам написать:
MyMultibyteString<int, std::vector> mbs;
Вот компиляции live example. Альтернативный способ написания выше, может быть:
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.
Единственное, на что вы должны обратить внимание, это то, что количество и тип аргументов в объявлении параметра шаблона шаблона должны точно соответствовать количеству и типу аргументов в определении соответствующего шаблона класса, который вы хотите передать как шаблон, независимо от того, что некоторые из этих параметров могут иметь значения по умолчанию.
Например, the class template std::vector
accepts two template parameters (тип элемента и тип распределителя), хотя второй имеет значение по умолчанию 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
, the std::set
class template accepts three template parameters.
Какой большой, основательный ответ. –
@ScottJones: Рад, что вы сочли это полезным :) –
@ScottJones Что касается вашего утверждения: 'Это означает, что вы не сможете написать один шаблон шаблона, который может принимать как std :: set, так и std :: vector': Would вариативные шаблоны решают проблему? http://stackoverflow.com/a/20499809/2436175 – Antonio