plantillas con arreglos c++ inheritance templates

con - plantillas c++



Herencia y plantillas en C++: ¿por qué los miembros heredados son invisibles? (5)

Creo que solo estás perdiendo un público: en la parte superior de la definición de Otra. Para preguntas como esta, generalmente es útil publicar los mensajes de error que está recibiendo.

Cuando una plantilla se hereda públicamente de otra plantilla, ¿no se supone que los métodos públicos de base sean accesibles?

template <int a> class Test { public: Test() {} int MyMethod1() { return a; } }; template <int b> class Another : public Test<b> { public: Another() {} void MyMethod2() { MyMethod1(); } }; int main() { Another<5> a; a.MyMethod1(); a.MyMethod2(); }

Bueno, GCC se equivoca en esto ... debo faltar algo totalmente obvio (fusión del cerebro). ¿Ayuda?


Debes calificar completamente MyMethod1 . El estándar C ++ lo indica claramente en 14.6.2 / 3:

En la definición de una plantilla de clase o un miembro de una plantilla de clase, si una clase base de la plantilla de clase depende de un parámetro de plantilla, el alcance de la clase base no se examina durante la búsqueda de nombre no calificado en el punto de definición de la clase plantilla o miembro o durante una instanciación de la plantilla de clase o miembro.

Entonces, deberías escribir:

void MyMethod2() { Test<b>::MyMethod1(); }


Esto es parte de las reglas concernientes a los nombres dependientes. Method1 no es un nombre dependiente en el alcance de Method2 . Así que el compilador no lo busca en clases base dependientes.

Hay dos formas de solucionarlo: utilizando this o especificando el tipo base. Más detalles sobre esta publicación muy reciente o en las Preguntas frecuentes de C ++ . Observe también que se perdió la palabra clave pública y un punto y coma. Aquí hay una versión fija de su código.

template <int a> class Test { public: Test() {} int MyMethod1() { return a; } }; template <int b> class Another : public Test<b> { public: Another() {} void MyMethod2() { Test<b>::MyMethod1(); } }; int main() { Another<5> a; a.MyMethod1(); a.MyMethod2(); }


Limpié tu código para esto:

template <int a> class Test { public: Test() {} int MyMethod1() { return a; } }; template <int b> class Another : public Test<b> { public: Another() {} void MyMethod2() { MyMethod1(); } }; int main() { Another<5> a; a.MyMethod1(); a.MyMethod2(); }

Y compilado con -fpermissive sin problemas (probablemente pueda resolver este problema).


main necesita un tipo de retorno.

Otra clase necesita un punto y coma que termina.

Otra clase necesita que sus miembros sean públicos.

Además, los métodos generalmente no se consideran invisibles; Los métodos eran inaccesibles sin la palabra clave de acceso público.