В C ++ существует три онтологических уровня: значения , типы и шаблоны .
Шаблон создания экземпляра является типом. Объект является определенного типа, и он имеет значение.
Все три вида объектов могут отображаться в качестве параметров шаблона:
template <int N, typename T, template <typename> C>
{
C<T> array[N];
};
Параметр в этом порядке классифицируется как «нетипичный параметр шаблона», «параметр шаблона» и «параметр шаблона шаблона» (я думаю).
Наличие параметров шаблона может быть очень полезным, например, если вы хотите разрешить параметризацию чего-либо в произвольных контейнерах (особенно с помощью шаблонов с переменными параметрами!):
template <typename T, template <typename...> Container>
void print(const Container<T> & c)
{ /* ... */ }
Между прочим, когда шаблон класса содержит члены, вы должны использовать слова typename
и template
, соответственно, чтобы обращаться к ним в соответствии с их природой (ничего не говоря, значит вы хотите сослаться на значение ):
template <typename T> struct Foo
{
T value;
typedef T * pointer;
template <typename S> struct Nested;
};
// now refer to them as:
Foo<T>::value;
typename Foo<T>::pointer;
template<typename S> Foo<T>::template Nested<S>;