2010-11-17 13 views
6

Considere el siguiente código C++,Los miembros de datos de la clase de plantilla base no son visibles en la clase de plantilla derivada?

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

llegué error de compilación: En función miembro void B<Derived>::foo():

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

¿Por qué? ¿Alguna buena solución?

+0

¿Qué compilador es este? –

+3

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

+3

@GMan haha ​​CRTP disfrazado :) –

Respuesta

13

Esto es porque usable_ es un nombre no dependiente, por lo que se busca en el momento en que se analiza la plantilla, en lugar de buscarse en instanciación (cuando se conoce la clase base).

La búsqueda de nombres no calificados no se buscará y los nombres no dependientes nunca se buscarán en clases base dependientes. Puede hacer que el nombre usable_ dependiente de la siguiente manera, que también se librará de nombre no calificado de búsqueda

this->usable_ = false; 

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

B::usable_ = false; 

Todo esto va a funcionar. O bien, puede declarar el nombre de la clase derivada con una declaración utilizando

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

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

Nótese que en C no habrá ningún problema - que sólo afecta a B.

+0

La última sesión de GotW habla de eso. Por desgracia, la siguiente solución bien escrita de Herb Sutter no se produjo. :( – wilhelmtell

Cuestiones relacionadas