2015-09-12 7 views
8

Я узнал, что вы можете создавать шаблоны с нулевыми параметрами. Хотя это не представляется возможным создавать их непосредственно, вы можете использовать шаблоны членовЧто вы можете сделать с шаблонами с нулевыми параметрами шаблона?

template<typename ...T> 
struct Maker { 
    template<T...> 
    struct HasNParams { }; 
}; 

Maker<>::HasNParams<> hnp; 

Интересно, должен ли он быть хорошо сформирован и что вы можете сделать с этими зверями. Можете ли вы передать их как аргументы шаблона и создать явные специализации (я предполагаю, что единственный сценарий для пустого случая)?

+2

Вопрос только в том, «что вы можете сделать с' SomeClassTemplate <> '?" Это поражает меня довольно широко. – Barry

+1

Быть общим? Что вы можете сделать с пустым 'vector'? – Jarod42

+0

@Barry вы не могли создать их pre-C++ 11, и я не видел приложений или статей о них. Это заставляет меня задаться вопросом, являются ли они случайностью, которую вы не должны использовать в своем коде? Или там используются, и что они? –

ответ

4

С риском озвучивания очевидной конечной рекурсивной инстанцирования.

template<typename Arg, typename ...T> 
struct Maker : public Maker<T...> 
{ 
    template<T...> 
    struct HasNmin1Params { }; 
}; 

Дело в том, что фактический список аргументов в Maker не является пустым, но мы используем только N-1 аргументы в HasNminOneParams.

+1

Спасибо, не могли бы вы привести пример? Я этого еще не вижу. –

1

Рассмотрим следующий шаблон класса:

template <typename... > struct typelist { }; 

Это метапрограммированием эквивалент контейнера. И так же, как полезно иметь пустой vector или map, полезно иметь пустой typelist. То есть что-то типа typelist<>. Вот два примера прецедентов для такой конструкции.

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

void foo(typelist<>) { } 

template <typename T, typename... Ts> 
void foo(typelist<T, Ts...>) { 
    bar<T>(); 
    foo(typelist<Ts...>{}); 
} 

Это может быть «возвращение» значение для metafunction, что указывает на состояние отказа.

template <typename F, typename T> 
struct filter_one 
: std::conditional_t<F::template apply<T>::value, 
        typelist<T>, 
        typelist<>> 
{ }; 

Какой помощник мы могли бы использовать, чтобы написать TypeList фильтр metafunction:

template <typename F, typename TL> 
struct filter; 

template <typename F, typename... Ts> 
struct filter<F, typelist<Ts...>> 
: concat_t<filter_one<F, Ts>...> 
{ }; 

Оба эти очень полезные особенности typelist<>, и это только один шаблон класса.

+0

Хмм, но у вас есть экземпляр шаблона с пустым пакетом параметров.В моем примере у нас есть шаблон без пакетов параметров, а просто нулевые параметры, например, в 'template <> struct Foo {}', созданные семантикой, а не синтаксисом (поскольку синтаксис зарезервирован для явной специализации). Я не вижу, как я могу передать ваш пример моему делу. –

+0

@ JohannesSchaub-litb У вас есть два пакета параметров в вашем примере. 'T' - это набор типов и неназванный пакет' T '. Это все еще пустой экземпляр пакета параметров. Вы спрашиваете конкретно о пустом пакете ценностей, какого-либо типа? – Barry

+0

Почему вторая неназванная пачка 'T's? Для меня это не имеет смысла, можете ли вы объяснить это дальше, пожалуйста? Для меня это просто расширение 'T' в список параметров и которое в моем случае приводит к 0 параметрам. –

Смежные вопросы