c++ - poo - herencia programacion
¿Es esto-> obligatorio acceder a los identificadores Base<T> de las clases derivadas? (2)
Clang es correcto.
$ 17.6.2 / 3 Nombres dependientes [temp.dep]
En la definición de una clase o plantilla de clase, el alcance de una clase base dependiente no se examina durante la búsqueda de nombres no calificados ni en el momento de la definición de la plantilla de clase o miembro, ni durante la instanciación de la plantilla o miembro de clase.
Para return data;
, los data
no están calificados , entonces se usará la búsqueda de nombres no calificada. Esto significa que no se debe encontrar el nombre en la clase base Base<T>
(que es una clase base dependiente porque depende del parámetro de la plantilla T
); es decir, los nombres no dependientes no se buscan en clases base dependientes.
this->data
o Base<T>::data
lo califica . Esto significa que el nombre se buscará en el momento de la creación de instancias, y en ese momento se conocerá la especialización base exacta que debe explorarse.
Este código se compila con MSVC 2015, pero no se compila con Clang 5.0.0 (tronco 304874):
template <typename T>
struct Base
{
T data;
};
template <typename T>
struct Derived : Base<T>
{
auto getData() const
{
return data;
}
};
Reemplazar data
con this->data
en Derived::getdata()
hace feliz a Clang.
¿Qué compilador es correcto según el estándar C ++?
¿Debe this->
ser utilizado en el código de plantilla para acceder a un identificador de una clase base?
Sí lo es. Básicamente, los data
dependen de T
Hay un mecanismo llamado búsqueda en dos fases. Los nombres que no dependen de la plantilla se resuelven inmediatamente, en el momento de la definición . Sus data
aún no existen, porque Base<T>
aún no existe, ya que no se creó una instancia . Por lo tanto, se queja de que no se encuentran los data
.
Debe indicarle al compilador que los data
dependen de la plantilla, y que la búsqueda de nombre se debe realizar en la segunda fase, después de que se sustituyan los parámetros de la plantilla, es decir, se creó una instancia de la clase de plantilla. Esto se puede hacer usando this
o proporcionando alcance dependiente de la plantilla.
Entonces, o bien this->f()
o Base<T>::f()
funcionarán.