2012-10-12 75 views
6

Estoy intentando compilar el siguiente fragmento de código del compilador, sin embargo, no parece ser un tema que me parece que no puede resolver:C++ y CRTP patrón de aplicación y el dilema

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; 
} 

cuando se compila wth tañido 3.1, el siguiente es el error:

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. 

creo que tiene algo que ver con la forma en que las plantillas se determinan en tiempo de compilación y si se determina como un tipo en el momento adecuado. También intenté agregar "using base_t :: count_t;" en vano. Aparte de eso, el diagnóstico producido por el compilador me ha dejado realmente perdido. Una respuesta o sugerencia sobre algo para leer acerca de este error sería apreciada.

Respuesta

2

count_x<x> no es un nombre calificado (no tiene ningún :: en absoluto), por lo que no puede precederse con typename.

Una vez que solucione esto, el código seguirá fallando debido a que el compilador aún no ha visto los typedefs anidados del tipo derivado al momento de crear la instancia de la base CRTP. Este other question muestra algunas alternativas.

+0

'Es un error utilizar el nombre de tipo desambiguador cuando no es necesario' en realidad, creo que es falso. –

+0

@Jesse Creo que fue un error en C++ 03, pero dejó de estar en C++ 11. –

+0

@Martinho: Hice ese cambio, ahora da otro conjunto de errores: c: \ clangllvm \ code \ example.cc: 10: 24: error: ningún tipo llamado 'count_t' en 'derivado <2>' typedef typename y: : count_t count_t; ~~~~~~~~~~~~^~~~~~~ c: \ clangllvm \ code \ example.cc: 15: 25: nota: en la creación de instancias de la clase de plantilla 'crtp_base >' solicitada aquí estructura derivada: crtp_base pública > ^ c: \ clangllvm \ code \ example.cc: 25: 15: nota: en instancia de clase de plantilla 'deriva <2>' solicitada aquí deriva <2> d ((count_x <2>())); – Switzy