2010-05-01 15 views
5

El siguiente código no se compila. Aparece un mensaje de error: error C2039: 'Asub': no ​​es miembro de 'C'Tipos "heredados" utilizando CRTP y typedef

¿Alguien me puede ayudar a entender esto?

Probado VS2008 & 2010 compilador.

template <class T> 
class B 
{ 
    typedef int Asub; 

public: 
void DoSomething(typename T::Asub it) 
{ 

} 
}; 

class C : public B<C> 
{ 
public: 
typedef int Asub; 

}; 

class A 
{ 
public: 
typedef int Asub; 

}; 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
C theThing; 
theThing.DoSomething(C::Asub()); 

return 0; 
} 
+1

usted debe siempre * * p rovide los números de línea con errores de compilación. – abelenky

+0

¿Qué es 'struct A' para en el ejemplo? – AlwaysLearning

Respuesta

7

usted está siendo un poco injusto para el compilador aquí - C es incompleta sin B<C> plenamente conocidas y al procesar B<C>, C sigue siendo un tipo incompleto. Hay hilos similares en comp.lang.c++.moderated y comp.lang.c++.

Tenga en cuenta que funciona si se demora la utilización por parte de llevarla a una definición de la función miembro, por ejemplo:

struct C : B<C> { 
    void f() { typedef typename C::Asub Asub; } 
}; 

Usted podría solucionar el problema, ya sea pasando los tipos de forma explícita al alza:

template<class T, class Asub> struct B { /* ... */ }; 
class C : B<C, int> { /* ... */ }; 

... o moviéndolos a alguna clase de rasgos si necesita pasar más:

template<class T, class Traits> struct B { 
    void DoSomething(typename Traits::Asub it) {} 
}; 

struct CTraits { 
    typedef int Asub; 
}; 

struct C : B<C, CTraits> { 
    typedef CTraits::Asub Asub;  
};