2015-03-12 17 views
13

Rozważmy następujący kod:Czy można utworzyć alias szablonu?

template< template< typename ... > class ... Ts > 
struct unite 
{ 
    template< typename ... T > 
    struct type 
     : Ts< T ... > ... 
    { }; 
}; 

// This does not work as ::type does not name a type, but a template: 

// template< template< typename ... > class ... Ts > 
// using unite_t = typename unite< Ts ... >::type; 

template<typename> struct debug_none {}; 
template<typename> struct debug_cout {}; 

template< typename ... > struct raise_demangled {}; 
template< typename ... > struct raise_specialized {}; 

template< typename, typename = int > struct match_default {}; 

template< template< typename ... > class Control > 
void f() 
{} 

int main() 
{ 
    f< unite< debug_none, raise_demangled, match_default >::type >(); 

    // Is there any way to create something like unite_t which works like this: 

    // f< unite_t< debug_none, raise_demangled, match_default > >(); 
} 

Live example

Pytanie: Czy istnieje jakiś sposób, aby stworzyć pewnego rodzaju "Szablon alias" podobny do typu alias? (patrz unite_t w powyższym przykładzie)

+1

Więc, pytanie: przypomniałem sobie, jak napisałem, że wcześniej zadałem to dokładne pytanie. Czy powinienem zamknąć mój http://stackoverflow.com/questions/17356487/equivalent-of-using-aliases-for-templates jako duplikat tego? Lub odwrotnie? :) – Yakk

+1

@Yakk Chociaż twoje pytanie jest dość podobne iw tym samym obszarze, nie sądzę, że jest to duplikat, ponieważ próbujesz pozbyć się słowa kluczowego "template" w innym miejscu. Jeśli rozwiązanie dla jednego * istnieje *, to * może * również rozwiązać inny problem - ale wydaje się, że nie ma rozwiązania. –

Odpowiedz

5

Nie, nie możesz.

może "zwrócić" typ lub zmienną. Nie może "zwrócić" numeru template. Nie ma podobnych mechanizmów gdzie indziej.

Można zrobić coś niejasno przydatnych przyjmując konwencję, że wszystkie szablony nie są szablony, ale zajęcia z template<?>using apply=?; alias wewnątrz nich (i podczas gdy jesteśmy w nim stałe są std::integral_constants<T,?>, a wskaźniki są pointer_constant<T*,?>).

Teraz wszystko jest klasą. template s stać tylko rodzaje klas (z ::apply<?...>

Zastosowanie wiązki typów do takiego szablonu będzie się odbywać za pomocą:.

template<class Z, class...Ts> 
using apply_t = Z::template apply<Ts...>; 

Więc z „natywnym” szablon Z, ty” d wykonaj Z<Ts...>. z tych „pośrednich” szablonów, można by zrobić apply_t<Z, Ts...>.

z niniejszą konwencją, szablon using alias może zwrócić szablon pośrednią. Jeśli reszta kodu następuje Conven Aby zawsze stosować szablon, aby zastosować szablon, a Ty pośrednio-ize wszystkie inne szablony, które napiszesz, skończymy.

To jest brzydkie.

+0

Czy istnieje propozycja rozwiązania tego problemu? – Brian

+0

@Brian nie, że znam. Potrzeba posiadania takich aliasów jest wątpliwa, ponieważ wymaga tego tylko względnie zaawansowane użycie języka C++, więc może nikt się nie przejmuje. – Yakk

+0

Dziękuję za odpowiedź, prawdopodobnie oznaczę to jako "zaakceptowany" wkrótce - "Nie, nie możesz" - część :) Niestety sugerowana alternatywa/obejście nie może być w moim przypadku używane, ponieważ spowodowałoby to interfejs (widoczny dla użytkownika) jeszcze bardziej skomplikowany/brzydki. Zastanawiam się nad odrzuceniem tego pomysłu, zamiast myląc użytkowników. –

Powiązane problemy