2012-10-12 11 views
6

Próbuję skompilować następujący fragment kodu kompilatora, jednak wydaje się, że problem, który nie wydaje się rozwiązać:C++ i CRTP realizacja wzór i dylemat

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

Kiedy skompilowany WTH brzękiem 3,1, co następuje błąd:

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. 

Uważam, że ma to coś wspólnego ze sposobem, szablony są określane w czasie kompilacji, a jeśli są one określane jako typ w odpowiednim czasie. Próbowałem również dodanie "using base_t :: count_t;" bez skutku. Poza tym diagnostyka generowana przez kompilator naprawdę mnie straciła. Pożądana byłaby odpowiedź lub sugestia dotycząca czegoś, co można przeczytać na temat tego błędu.

Odpowiedz

2

count_x<x> nie jest kwalifikowaną nazwą (w ogóle nie ma ::), więc nie może być poprzedzone typename.

Gdy to naprawisz, kod nadal będzie się nie sprawdzał, ponieważ zagnieżdżone typy nie były widziane przez kompilator jeszcze podczas tworzenia bazy CRTP. Ten other question pokazuje kilka alternatyw.

+0

"Błędem jest używanie disambiguatora nazw plików, gdy nie jest to potrzebne" faktycznie uważam, że jest to fałsz. –

+0

@Jesse Wierzę, że był to błąd w C++ 03, ale przestał być w C++ 11. –

+0

@Martinho: Wprowadziłem tę zmianę, teraz daje to inny zestaw błędów: c: \ clangllvm \ code \ example.cc: 10: 24: error: no type o nazwie 'count_t' w 'wyprowadzone <2>' typedef nazwa_typu y: : count_t count_t; ~~~~~~~~~~~~^~~~~~~ c: \ clangllvm \ code \ example.cc: 15: 25: Uwaga: w instancji klasy szablonu 'crtp_base >' zwróciła tutaj struct pochodzi: crtp_base publicznego > ^ c: \ clangllvm \ code \ example.cc: 25: 15: Uwaga: w instancji klasy szablonu 'pochodzi <2>' o tu pochodzi <2> d ((count_x <2>())); – Switzy