Herencia y plantillas en C ++: ¿por qué los métodos son invisibles?

Cuando una plantilla hereda públicamente de otra plantilla, ¿no se supone que los métodos públicos básicos son accesibles?

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

Bueno, GCC se aprovecha de esto … Me falta algo totalmente obvio (derretimiento del cerebro). ¿Ayuda?

Esto es parte de las reglas relativas a los nombres dependientes. Method1 no es un nombre dependiente en el scope de Method2 . Entonces el comstackdor no lo busca en clases base dependientes.

Hay dos formas de solucionarlo: usar this o especificar el tipo de base. Más detalles sobre esta publicación muy reciente o en las preguntas frecuentes de C ++ . También tenga en cuenta que se perdió la palabra clave pública y un punto y coma. Aquí hay una versión fija de tu código.

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

Debe calificar completamente MyMethod1 . El estándar C ++ establece esto claramente en 14.6.2 / 3:

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

Entonces, debes escribir:

 void MyMethod2() { Test::MyMethod1(); } 

principal necesita un tipo de devolución.

clase Otra necesita un punto y coma de terminación.

clase Otra 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.

Limpié tu código a esto:

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

Y comstackdo con -fpermissive sin problemas (probablemente puedas resolver este problema).

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