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
class
o 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 .