c++ - plusplus - Heredar de tipo const pasado como parámetro de plantilla
c++ website (1)
El siguiente código no es válido:
struct base {
};
struct inherit : const base {
};
No se puede heredar de un tipo const .
¿Cambia la situación cuando se trata de plantillas? En otras palabras, este código es válido:
struct base {
};
template<typename T>
struct inherit : T {
using T::T;
};
int main() {
inherit<base const>{};
}
gcc dice que está bien, pero clang informa
<source>:6:2: error: ''const base'' is not a direct base of ''inherit<const base>'', cannot inherit constructors
using T::T;
^ ~
<source>:10:2: note: in instantiation of template class ''inherit<const base>'' requested here
inherit<base const>{};
^
1 error generated.
Compiler returned: 1
Para hacer feliz a Clang, necesito hacer algo como esto:
template<typename T>
struct inherit : T {
using U = std::remove_const_t<T>;
using U::U;
};
¿Qué versión es correcta? ¿O ninguno de ellos es correcto y necesito heredar de std::remove_const_t<T> ?
Gracias a T.C. tenemos:
Según [temp.param]/3 :
Un parámetro de tipo cuyo identificador no sigue una elipsis define su identificador como un nombre typedef (si se declara con
classo nombretypename) ... en el alcance de la declaración de plantilla.
Así que funciona igual que un typedef .
Y luego [class.name]/5 :
Si se utiliza un typedef-name que nombra un tipo de clase calificado por el cv cuando se requiere un nombre de clase , se ignoran los calificadores del cv .
Por lo tanto, GCC tiene razón, se debe const cuando se hereda de T , ya que se requiere un nombre de clase en ese punto , así como en el using T::T; Declaración de constructores herederos .