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
ortypename
) ... in the scope of the template declaration.
So it works just like a typedef
.
And then [class.name]/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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With