2010-05-01 5 views
5

Le code suivant ne compile pas. Je reçois un message d'erreur: erreur C2039: 'Asub': n'est pas un membre de 'C'Types "Hérité" utilisant CRTP et typedef

Quelqu'un peut-il m'aider à comprendre cela?

Essayé VS2008 & 2010 compilateur.

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

vous devriez * toujours * p Fournir des numéros de ligne avec des erreurs de compilation. – abelenky

+0

Qu'est-ce que 'struct A' pour dans l'exemple? – AlwaysLearning

Répondre

7

Vous êtes un peu injuste au compilateur ici - C est incomplète sans B<C> entièrement connus et lors du traitement B<C>, C est encore un type incomplet. Il existe des threads similaires sur comp.lang.c++.moderated et comp.lang.c++.

Notez que cela fonctionne si vous retardez l'utilisation en le déplaçant dans une définition de fonction de membre, par exemple:

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

Vous pouvez contourner le problème soit en passant les types explicitement vers le haut:

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

... ou en les déplaçant dans une certaine classe de traits si vous avez besoin de passer plus:

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