Каково некоторое использование шаблонных шаблонных параметров?

220
задан Rakete1111 8 August 2018 в 09:06
поделиться

3 ответа

Я думаю, что необходимо использовать шаблонный шаблонный синтаксис для передачи параметра, тип которого является шаблоном, зависящим от другого шаблона как это:

template <template<class> class H, class S>
void f(const H<S> &value) {
}

Здесь, H шаблон, но я хотел, чтобы эта функция имела дело со всеми специализациями H.

ПРИМЕЧАНИЕ : я программировал C++ много лет и только нуждался в этом однажды. Я нахожу, что это - редко необходимая функция (конечно, удобный при необходимости в нем!).

я пытался думать о хороших примерах, и честно говоря, большую часть времени это не необходимо, но давайте изобретете пример. Давайте притворимся, что std::vector не делает , имеют typedef value_type.

Поэтому, как Вы записали бы функцию, которая может создать переменные правильного типа для элементов векторов? Это работало бы.

template <template<class, class> class V, class T, class A>
void f(V<T, A> &v) {
    // This can be "typename V<T, A>::value_type",
    // but we are pretending we don't have it

    T temp = v.back();
    v.pop_back();
    // Do some work on temp

    std::cout << temp << std::endl;
}

ПРИМЕЧАНИЕ : у нас std::vector есть два шаблонных параметра, тип и средство выделения, таким образом, мы должны были принять их обоих. К счастью, из-за вычета типа, мы не должны будем выписывать точный тип явно.

, который можно использовать как это:

f<std::vector, int>(v); // v is of type std::vector<int> using any allocator

или еще лучше, мы можем просто использовать:

f(v); // everything is deduced, f can deal with a vector of any type!

ОБНОВЛЕНИЕ : Даже этим изобретенным примером, в то время как иллюстративный, больше не является удивительный пример из-за C++ 11 представлений auto. Теперь та же функция может быть записана как:

template <class Cont>
void f(Cont &v) {

    auto temp = v.back();
    v.pop_back();
    // Do some work on temp

    std::cout << temp << std::endl;
}

, который является, как я предпочел бы писать этот тип кода.

186
ответ дан Evan Teran 23 November 2019 в 04:07
поделиться

Вот простой пример, взятый от 'современный Дизайн C++ - Универсальные Шаблоны программирования и Шаблоны разработки, Примененные' Andrei Alexandrescu:

Он использует классы с шаблонными шаблонными параметрами для реализации шаблона политики:

// Library code
template <template <class> class CreationPolicy>
class WidgetManager : public CreationPolicy<Widget>
{
   ...
};

Он объясняет: Как правило, класс хоста уже знает или может легко вывести, аргумент шаблона класса политики. В примере выше, WidgetManager всегда управляет объектами Виджета типа, таким образом требуя, чтобы пользователь определил, что Виджет снова в инстанцировании CreationPolicy избыточен и потенциально опасен. В этом случае код библиотеки может использовать шаблонные шаблонные параметры для определения политик.

эффект состоит в том, что клиентский код может использовать 'WidgetManager' более изящным способом:

typedef WidgetManager<MyCreationPolicy> MyWidgetMgr;

Вместо более громоздкого, и подверженного ошибкам способа, которым потребовал бы недостающий шаблон определения аргументы шаблона:

typedef WidgetManager< MyCreationPolicy<Widget> > MyWidgetMgr;
64
ответ дан yoav.aviram 23 November 2019 в 04:07
поделиться

Я использую его для имеющих версию типов.

, Если Вам присвоили версию типу через шаблон такой как MyType<version>, можно записать функцию, в которой можно получить номер версии:

template<template<uint8_t> T, uint8_t Version>
Foo(const T<Version>& obj)
{
    assert(Version > 2 && "Versions older than 2 are no longer handled");
    ...
    switch (Version)
    {
    ...
    }
}

, Таким образом, можно сделать разные вещи в зависимости от версии типа, передаваемого во вместо того, чтобы иметь перегрузку для каждого типа. У Вас могут также быть функции преобразования, которые берут в MyType<Version> и возврат MyType<Version+1>, универсальным способом, и даже рекурсивно вызывают их, чтобы иметь ToNewest() функция, которая возвращает последнюю версию типа от любой более старой версии (очень полезный для журналов, которые, возможно, были сохранены некоторое время назад, но потребность, которая будет обработана с сегодняшним новейшим инструментом).

0
ответ дан 23 November 2019 в 04:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: