tour plusplus plus oficial documentacion c++ c++11 c++14 language-lawyer

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 nombre typename ) ... 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 .