2010-11-17 7 views
6

Considérez ce qui suit le code C++,Les membres de données de classe de modèle de base ne sont pas visibles dans la classe de modèle dérivée?

template <typename Derived> 
struct A 
{ 
    bool usable_; 
}; 

template <typename Derived> 
struct B : A< B<Derived> > 
{ 
    void foo() 
    { 
     usable_ = false; 
    } 
}; 

struct C : B<C> 
{ 
    void foo() 
    { 
     usable_ = true; 
    } 
}; 

int main() 
{ 
    C c; 
} 

Je suis erreur de compilation: En fonction membre void B<Derived>::foo():

template_inherit.cpp:12: error: 'usable_' was not declared in this scope.

Pourquoi? Une bonne solution?

+0

De quel compilateur s'agit-il? –

+3

'struct B: A < B>' wat. – GManNickG

+3

@GMan haha ​​CRTP déguisé :) –

Répondre

13

Parce que usable_ est un nom non dépendant, il est recherché au moment de l'analyse du modèle, au lieu d'être recherché à l'instanciation (lorsque la classe de base est connue).

La recherche de nom non qualifié ne recherche pas et les noms non dépendants ne sont jamais recherchés dans les classes de base dépendantes. Vous pouvez faire le nom usable_ dépend de la manière suivante, qui sera également se débarrasser de nom non qualifié recherche

this->usable_ = false; 

// equivalent to: A<B>::usable_ = false; 
A< B<Derived> >::usable_ = false; 

B::usable_ = false; 

Tous ces éléments vont travailler. Ou vous pouvez déclarer le nom dans la classe dérivée avec l'aide-déclaration

template <typename Derived> 
struct B : A< B<Derived> > 
{ 
    using A< B<Derived> >::usable_; 

    void foo() 
    { 
     usable_ = false; 
    } 
}; 

Notez que dans C il n'y aura pas de problème - il ne touche que B.

+0

Le dernier GotW en parle. Hélas, la solution habituelle bien écrite d'Herb Sutter n'a pas suivi. :( – wilhelmtell

Questions connexes