Для чего нужны template template parameters
в шаблонных классах и функциях, ведь можно передавать им аргументы, которые являются шаблонами, с помощью обычных type parameters
?
Это смотря что вы имеете в виду под "передавать им аргументы, которые являются шаблонами, с помощью обычных 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;
Из вашего вопроса не ясно, о каком именно из этих двух пунктов вы ведете речь.
Например чтобы делегировать инстанцирование этого шаблона целевому шаблону. Т.е. предоставить ему возможность самостоятельно выбирать параметры для передаваемого шаблона. Например:
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>;
};
Виртуальный выделенный сервер (VDS) становится отличным выбором
У меня есть класс, у него два объекта: window2, window3Как настроить виджеты (установить параметры кнопок, например) именно в window3 не зависимо от window2?
Для чего вообще нужны типы в языке? Разве не проще было бы писать везде auto или вообще не указывать ничего перед именем переменной?
Какой тип имеет указатель на член класса? Другими словами, что нужно подставить здесь, чтобы работало? Очевидное int* не работает