2012-10-12 8 views
6

Ich versuche, das folgende Stück Code zu kompilieren, aber es scheint ein Problem zu sein, dass ich nicht zu lösen scheinen:C++ und CRTP Muster Implementierung und Compiler Dilemma

template <int x> 
struct count_x 
{ 
    enum { x_size = x }; 
}; 

template <typename y> 
struct crtp_base 
{ 
    typedef typename y::count_t count_t; 
    crtp_base(const count_t&){} 
}; 

template <int x> 
struct derived : public crtp_base<derived<x> > 
{ 
    typedef typename count_x<x> count_t; 
    typedef crtp_base<derived<x> > base_t; 
    derived(const count_t& c) : base_t(c){} 
}; 


int main() 
{ 
    derived<2> d((count_x<2>())); 
    return 0; 
} 

Wenn wth Klirren zusammengestellt 3.1 ist die folgende der Fehler:

c:\clangllvm\code\example.cc:18:21: error: expected a qualified name after 'typename' 
    typedef typename count_x<x> count_t; 
        ^
c:\clangllvm\code\example.cc:18:21: error: typedef name must be an identifier 
    typedef typename count_x<x> count_t; 
        ^~~~~~~~~~ 
c:\clangllvm\code\example.cc:18:28: error: expected ';' at end of declaration list 
    typedef typename count_x<x> count_t; 
         ^
          ; 
c:\clangllvm\code\example.cc:20:18: error: no template named 'count_t'; did you mean 'count_x'? 
    derived(const count_t& c) 
       ^~~~~~~ 
       count_x 
c:\clangllvm\code\example.cc:2:8: note: 'count_x' declared here 
struct count_x 
    ^
c:\clangllvm\code\example.cc:20:18: error: use of class template count_x requires template arguments 
    derived(const count_t& c) 
       ^
c:\clangllvm\code\example.cc:2:8: note: template is declared here 
struct count_x 
    ^
5 errors generated. 

ich glaube, es etwas zu tun mit der Art und Weise bekommen hat die Vorlagen bei der Kompilierung festgelegt werden und wenn sie als eine Art zum richtigen Zeitpunkt bestimmt. Ich habe auch versucht, "using base_t :: count_t;" ohne Erfolg hinzuzufügen. Abgesehen davon hat mich die vom Compiler erzeugte Diagnose wirklich verloren. Eine Antwort oder eine Anregung zu etwas, das über diesen Fehler gelesen werden kann, wäre willkommen.

Antwort

2

count_x<x> ist kein qualifizierter Name (es hat überhaupt keine ::!), Daher kann typename nicht vorangestellt werden.

Sobald Sie dies beheben, wird der Code weiterhin fehlschlagen, da die geschachtelten typedefs des abgeleiteten Typs vom Compiler noch nicht gesehen wurden, wenn er die CRTP-Basis instanziiert. Diese other question zeigt einige Alternativen.

+0

'Es ist ein Fehler, den Typname Disambiguator zu verwenden, wenn es nicht benötigt wird 'tatsächlich denke ich, dass das falsch ist. –

+0

@Jesse Ich glaube, es war ein Fehler in C++ 03, aber nicht mehr in C++ 11. –

+0

@Martinho: Ich habe diese Änderung gemacht, es gibt jetzt eine andere Reihe von Fehlern: c: \ clangllvm \ code \ example.cc: 10: 24: Fehler: kein Typ mit dem Namen 'count_t' in 'abgeleitete ' typedef typename y: : count_t count_t; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ c: \ clangllvm \ code \ beispiel.cc: 15: 25: Hinweis: bei Instanziierung der Template-Klasse 'crtp_base >' hier angefordert Struktur abgeleitet: public crtp_base > ^ c: \ clangllvm \ code \ example.cc: 25: 15: Anmerkung: in Instantiierung der Template-Klasse 'abgeleitet <2>' angefordert hier abgeleitet <2> d ((count_x <2>())); – Switzy