2015-03-27 25 views
5

Zastanawiam się nad możliwymi implementacjami std::tuple (i wszelkich podobnych klas szablonów ze zmienną liczbą "członków" zdefiniowanych w czasie kompilacji), i pomyślałem może można utworzyć "typ rekursywny" przypominający listę połączoną. Próbowałem kompilowanie następujący przypadek testowy:Tworzenie podobnej do krotki "połączonej listy" kompilacji z szablonami variadic

template <typename FirstType, typename... OtherTypes> 
class TupleLite 
{ 
    public: 
    FirstType type_; 
    TupleLite<OtherTypes...> other_types_; 
}; 

int main() 
{ 
    TupleLite<int,double> mytuple; 
} 

Klasa sama kompiluje bez błędów, ale instancji wyrzuca błąd wrong number of template arguments (0, should be 1 or more). Wierzę, że dzieje się tak, ponieważ TupleLite<int, double> próbuje utworzyć instancję TupleLite<double>, która próbuje utworzyć instancję TupleLite<>, dla której nie ma poprawnej definicji.

Czy ta "rekursywnie sklasyfikowana klasa" może zostać uratowana? Próbowałem definiowania „specjalizację no-argument” z TupleLite następująco:

template <> 
class TupleLite {} 

.... ale to nie wydają się działać, choć g++ i clang++ wydają się nie zgadzają się dokładnie dlaczego.

Od g++, najbardziej istotne błędy wydają się być:

error: template specifiers not specified in declaration of ‘template<class FirstType, class ... OtherTypes> class TupleLite’ 
    class TupleLite 
     ^
error: wrong number of template arguments (0, should be 1 or more) 
TupleLite<OtherTypes...> other_types_; 
         ^

clang++ jednak mówi:

error: extraneous 'template<>' in declaration of class 'TupleLite' 
template <> 
^ 
error: redefinition of 'TupleLite' as different kind of symbol 
class TupleLite 
    ^
+1

Słyszeliście o ['TypeList'] (http://loki-lib.sourceforge.net/html/a00681.html)? –

+0

@RSahu Nie, nie miałem. –

+0

... Ale '' szablon <> klasa TupleLite {} '' jest poprawna C++ 11? – Cinch

Odpowiedz

3

Podstawowa definicja szablon TupleLite określa, że ​​wymaga co najmniej jeden szablon argumentu , FirstType. Ponieważ to nie to, co chcesz, aby wyrazić to, zapewniają podstawowy szablon defition który kończy się również trzymając pusty sprawę tak:

template <typename...> 
class TupleLite{}; 

i jeden częściowe Specjalności:

template <typename FirstType, typename... OtherTypes> 
class TupleLite<FirstType, OtherTypes...> 
{ 
    public: 
    FirstType type_; 
    TupleLite<OtherTypes...> other_types_; 
}; 

Coliru Demo.

EDYCJA: Dzięki Nikos za wskazanie, że pusta specyfikacja nie była potrzebna w tym przypadku.

+1

Nie potrzebujesz specjalizacji pustych argumentów. Po prostu zdefiniuj szablon podstawowy: [demo] (http://coliru.stacked-crooked.com/a/db65288a2503dfa8) –

+0

@NikosAthanasiou Ah tak. Dzięki! Edytowane. – Pradhan

+0

Ah, to ma sens. Dziękuję Ci. –

Powiązane problemy