7

Czy istnieje prosty sposób, aby mieć variadic variadic szablon szablonów parametrów. Na przykład rozważmy następujący podpis funkcjaVariadic variadic szablon szablon parametry

template<template<typename,size_t...> class Pack, 
    typename T, size_t ... Args> 
void foo(const Pack<T,Args...>& a); 

Jeśli chcemy przekazać dwa Pack s musimy teraz zrobić przeciążenia

template<template<typename,size_t...> class Pack, 
    typename T, size_t ... Args0, size_t ... Args1> 
void foo(const Pack<T,Args0...>& a, const Pack<T,Args1...>& b); 

Teraz co, jeśli chcemy przekazać zmienną liczbę obiektów Pack z różnymi parametrami variadic np Args0...,Args1...,Args2....

Tak więc zastanawiałem się, czy istnieje praktyczny sposób robienia czegoś wzdłuż linii (z pewnością jest to reprezentacja szkicu).

template<template<typename,size_t...> ... class Pack, typename T,...> 
void foo(const Pack<T,...> ... packs); 
+0

Co należy zrobić z 'T' i' Args'? Lepiej byłoby po prostu użyć 'szablonu ' i napisać kilka prostych cech, aby wyodrębnić to, czego potrzebujesz. – TartanLlama

+0

..... lol .....? : D –

+0

@Klaus właściwie, tak możesz ... [Zobacz sam] (http://coliru.stacked-crooked.com/a/1d822071ce2130bf) – Rerito

Odpowiedz

5

chciałbym po prostu użyć zwykłej zmiennej liczbie argumentów szablonu:

template<typename... Ts> 
void foo(const Ts&... packs) { 

} 

Następnie należy napisać cechę wyodrębnić rodzaj i size_t s. Możesz łatwo dodać szablony aliasów pomocników, aby zrobić cokolwiek chcesz.

template <typename T> struct extract_args; 

template <template <typename, size_t...> class Pack, typename T, size_t... Args> 
struct extract_args<Pack<T,Args...>> { 
    using type = T; 
    using args = std::index_sequence<Args...>; 
}; 

Następnie w ciągu foo można wyodrębnić argumenty i wykorzystywać je jednak chcesz. Na przykład, aby uzyskać std::tuple zawierające wszystkie T s od talii:

using all_ts = std::tuple<typename extract_args<Ts>::type...>; 
3

proponuję Ci zarządzać Pack argumenty rekursywnie, w ten sposób

#include <array> 

template <typename T, std::size_t ... Args> 
struct testS 
{ }; 

void foo() 
{ /* terminal iteration */ } 

template <template <typename, std::size_t...> class Pack, 
      typename T, std::size_t ... Args, typename ... Packs> 
void foo (const Pack<T, Args...> pack0, Packs ... packs) 
{ 
    // do something with pack0 

    foo(packs...); 
} 

int main() 
{ 
    foo(testS<int>{}, std::array<long, 5U>{}, testS<char, 7U, 9U, 11U>{}); 

    return 0; 
} 

--- Edit ---

Zmodyfikowany przykład pokazujący użycie z różnymi typami i zmienną liczbą parametrów szablonu std::size_t.

+0

To rozwiązanie działa całkiem nieźle. Możesz wywołać 'foo' z wieloma typami szablonów, włączając te, które (w przeciwieństwie do' std :: array') przyjmują więcej niż jeden parametr szablonu 'size_t'. – Smeeheey

+0

@Smeeheey - exact: działa z wieloma typami szablonów ze zmienną liczbą parametrów szablonu "std :: size_t". Zmodyfiowałem przykład, próbując go podkreślić. Dzięki. – max66