Для чего нужны template template parameters?

152
26 апреля 2019, 13:10

Для чего нужны template template parameters в шаблонных классах и функциях, ведь можно передавать им аргументы, которые являются шаблонами, с помощью обычных type parameters?

Answer 1

Это смотря что вы имеете в виду под "передавать им аргументы, которые являются шаблонами, с помощью обычных type parameters".

  • Шаблон является шаблоном только пока у него остались незафиксированные параметры. Когда для всех параметров шаблона указаны конкретные аргументы это уже никакой не шаблон. Шаблон функции превращается в обычную функцию, а шаблон типа - в обычный тип. Поэтому, с одной стороны, когда вы передаете через type parameters уже специализированный шаблон, то такой шаблон уже не является шаблоном. Это уже просто тип, готовый "замороженный" конкретный тип, в котором не осталось ничего шаблонного. Его в общем случае уже нельзя "переспециализовать" в другой тип.

    А template template parameters - это не окончательно отлитые в граните типы, это еще живые подвижные шаблоны. Их можно свободно специализировать налево и направо с разными аргументами. Например

    template <template <typename T, typename = std::allocator<T>> class Container> struct S
    {
      Container<int> ints;
      Container<double> doubles;
    };
    ...
    S<std::vector> sv;
    S<std::list> sl;
    

    Каким образом вы собираетесь это делать через "обычный type parameter"?

  • С другой стороны, шаблоны действительно можно передавать через "обычные type parameters". Шаблон можно объявить членом обычного класса, а затем передавать этот обычный класс через "обычный type parameter", тем самым вместе с ним передавая и "завернутый" в него шаблон. То есть с этой точки зрения template template parameters являются избыточными (как, впрочем, и template non-type parameters) - всех их можно симулировать через обычные type parameters.

    Отвечая на свой же вопрос, заданный выше

    struct TraitsV
    {
      template <typename T, typename A = std::allocator<T>> 
      using Container = std::vector<T, A>;
    };
    struct TraitsL
    {
      template <typename T, typename A = std::allocator<T>> 
      using Container = std::list<T, A>;
    };
    template <typename Traits> struct S
    {
      typename Traits::template Container<int> ints;
      typename Traits::template Container<double> doubles;
    };
    ...
    S<TraitsV> sv;
    S<TraitsL> sl;
    

Из вашего вопроса не ясно, о каком именно из этих двух пунктов вы ведете речь.

Answer 2

Например чтобы делегировать инстанцирование этого шаблона целевому шаблону. Т.е. предоставить ему возможность самостоятельно выбирать параметры для передаваемого шаблона. Например:

template
<
    typename x_Value
,   template
    <
         typename xx_Value
    ,    typename xx_Allocator
    > class x_Container
> class t_Fancy
{
    private: class
    t_CustomAllocator{...};
    private: using
    t_Container = x_Container<x_Value, t_CustomAllocator>;
};
READ ALSO
Как настроить виджеты объекта класса

Как настроить виджеты объекта класса

У меня есть класс, у него два объекта: window2, window3Как настроить виджеты (установить параметры кнопок, например) именно в window3 не зависимо от window2?

150
fstream c++ keylogger

fstream c++ keylogger

Есть зацикленная функция, которая записывает нажатия клавиши в txt файл

311
Зачем нужны типы?

Зачем нужны типы?

Для чего вообще нужны типы в языке? Разве не проще было бы писать везде auto или вообще не указывать ничего перед именем переменной?

190
Тип указателя на член класса

Тип указателя на член класса

Какой тип имеет указатель на член класса? Другими словами, что нужно подставить здесь, чтобы работало? Очевидное int* не работает

177