Heredar del tipo const pasado como parámetro de plantilla


El siguiente código no es válido:

struct base {
};

struct inherit : const base {
};

No puede heredar de un tipo const.

¿Cambia la situación cuando se trata de plantillas? En otras palabras, ¿es válido este código:

struct base {
};

template<typename T>
struct inherit : T {
    using T::T;
};

int main() {
    inherit<base const>{};
}

El CCG 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>?

Author: David Stone, 2018-05-25

1 answers

Gracias a @T. C. tenemos:

Según [temp.param]/3:

Un parámetro de tipo cuyo identificador no sigue puntos suspensivos define su identificador como un typedef-name (si se declara con class o typename)... en el ámbito de aplicación de la declaración de plantilla.

Así que funciona como un typedef.

Y luego [class.name]/5:

If a typedef-name that names a cv-qualifiedel tipo de clase se usa cuando se requiere un class-name, los cv-qualifiers se ignoran.

Por lo tanto GCC es derecho, const debe ser despojado cuando hereda de T, ya que class nombre es necesario en ese punto, así como en la using T::T; heredar constructores declaración.

 16
Author: rustyx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-27 12:37:50