Inherit from const type passed as template parameter

  • A+

The following code is not valid:

struct base { };  struct inherit : const base { }; 

You cannot inherit from a const type.

Does the situation change when templates are involved? In other words, is this code valid:

struct base { };  template<typename T> struct inherit : T {     using T::T; };  int main() {     inherit<base const>{}; } 

gcc is says it is fine, but clang reports

<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 

To make clang happy, I need to do something like this:

template<typename T> struct inherit : T {     using U = std::remove_const_t<T>;     using U::U; }; 

Which version is correct? Or are neither of them correct and I need to inherit from std::remove_const_t<T>?

Thanks to @T.C. we have:

According to [temp.param]/3:

A type-parameter whose identifier does not follow an ellipsis defines its identifier to be a typedef-name (if declared with class or typename) ... in the scope of the template declaration.

So it works just like a typedef.

And then []/5:

If a typedef-name that names a cv-qualified class type is used where a class-name is required, the cv-qualifiers are ignored.

Hence GCC is right, const should be stripped when inheriting from T, since a class-name is required at that point, as well as in the using T::T; inheriting constructors declaration.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: