2015-09-12 12 views
8

Nauczyłem się jakiś czas temu, że możesz tworzyć szablony z zerowymi parametrami. Chociaż nie jest to możliwe, aby utworzyć je bezpośrednio, można użyć szablonów członkówCo można zrobić z szablonami z zerowymi parametrami szablonu?

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

Maker<>::HasNParams<> hnp; 

Zastanawiam się, czy to ma być dobrze wykształcona i co można zrobić z tymi zwierzętami. Czy możesz przekazać je jako argumenty szablonu i utworzyć wyraźne specjalizacje (domyślam się, że jedynym scenariuszem jest wtedy pusta sprawa)?

+2

Czy to pytanie brzmi "co można zrobić z' SomeClassTemplate <> '?" To wydaje mi się dość szerokie. – Barry

+1

Być ogólnikiem? Co możesz zrobić z pustym 'wektorem'? – Jarod42

+0

@Barry nie można utworzyć ich przed C++ 11 i nie widziałem aplikacji ani artykułów na ich temat. Zastanawiam się, czy to przypadek, którego nie powinieneś używać w swoim kodzie? Czy są jakieś zastosowania i czym one są? –

Odpowiedz

4

Istnieje ryzyko, że brzmi to w sposób oczywisty, kończąc tworzenie rekursywne.

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

Chodzi o to, że rzeczywista lista argument Maker nie jest pusta, ale używamy tylko N-1 argumenty HasNminOneParams.

+1

Dzięki, czy możesz zrobić przykład? Jeszcze tego nie widzę. –

1

rozważyć następujące klasy szablonu:

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

Jest to odpowiednik metaprogramowanie z pojemnika. I w ten sam sposób, w jaki użyteczne jest posiadanie pustego vector lub map, przydatne jest posiadanie pustego typelist. To znaczy coś w rodzaju typelist<>. Oto dwa przykładowe przypadki użycia dla takiej konstrukcji.

To może być warunek zakończenia dla typu rekursji:

void foo(typelist<>) { } 

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

To może być „powrót” wartość dla metafunkcji, wskazując stan awarii.

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

Który jest pomocnikiem mogliśmy korzystać napisać metafunkcji filtra typelist:

template <typename F, typename TL> 
struct filter; 

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

Oba te są bardzo użyteczne cechy typelist<>, a to tylko jeden szablon klasy.

+0

Hmm, ale to, co tam masz, to tworzenie szablonów z pustym pakietem parametrów.W moim przykładzie mamy szablon bez paczek parametrów, ale po prostu zero parametrów, jak w 'template <> struct Foo {}', tworzonych przez semantykę zamiast składni (ponieważ składnia jest zarezerwowana dla jawnej specjalizacji). Nie widzę, jak mogę przenieść twój przykład do mojej sprawy. –

+0

@ JohannesSchaub-litb Masz dwa pakiety parametrów w twoim przykładzie. 'T' to paczka typów i nienazwana paczka' T's. To wciąż pusta instancja zestawu parametrów. Czy pytasz konkretnie o pusty pakiet wartości, bez typu? – Barry

+0

dlaczego druga jest bezimienną paczką "T"? To nie ma dla mnie sensu, czy możesz wyjaśnić to dalej? Dla mnie jest to tylko rozwinięcie 'T' do listy parametrów, które w moim przypadku daje 0 parametrów. –

Powiązane problemy