While refactoring some C++11 code, I stumbled upon a strange thing. Namely, it seems to be impossible to define a CV-qualified (const
, volatile
or const volatile
) base class, e.g:
struct A { int a = 0; };
struct B: A const {}; // Error here with Clang and GCC!
However, the following compiles without errors:
struct A { int a = 0; };
using AC = A const;
struct B: AC {}; // NO ERROR HERE!? Qualifiers are ignored.
int main() {
B b;
b.a = 42; // NO ERROR modifying a field of const base.
return b.a;
}
I have two questions:
PS: Since this is a language-lawyer question, please provide references to the C++ standard.
The grammar prohibits it. The base classes are specified with the base-clause production specified at the start of section 10 of the standard. It eventually resolves to base-type-specifier, which is class-or-decltype, which is either a decltype
construct or a nested-name-specifier[opt] class-name. Note that this leaves no place for a cv-specifier.
The typedef name fits in the grammar. 9.1/5 says "A typedef-name that names a class type, or a cv-qualified version thereof, is also a class-name." The const is simply ignored.
The const is simply ignored. Base class subobjects cannot be const on their own. 9.1/5 says "If a typedef-name that names a cv-qualified class type is used where a class-name is required, the cv-qualifiers are ignored."
It is actually the full object you create that is const or not const, classes are not cv-qualified.
In using AC = A const;
the const is simply ignored when used for inheriting.
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