Подтвердить что ты не робот

CV-квалифицированные базовые классы в С++

Во время рефакторинга кода С++ 11 я наткнулся на странную вещь. А именно, представляется невозможным определить базовый класс с квалификацией CV (const, volatile или const volatile), например:

struct A { int a = 0; };
struct B: A const {}; // Error here with Clang and GCC!

Однако следующие компиляции без ошибок:

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;
}

У меня есть два вопроса:

  • Что в стандартах С++ запрещает определять базовый класс с квалификацией CV, если вообще?
  • Почему второй пример компилируется?

PS: Поскольку это вопрос language-lawyer, просьба указать ссылки на стандарт С++.

4b9b3361

Ответ 1

  • Грамматика запрещает это. Базовые классы задаются производством базового предложения, указанным в начале раздела 10 стандарта. В конечном итоге он решает спецификатор базового типа, который является классом-или-decltype, который является либо конструкцией decltype, либо именем класса-в-вложенном-name-specifier [opt]. Обратите внимание, что это не оставляет места для cv-спецификатора.

  • Имя typedef соответствует грамматике. 9.1/5 говорит: "Имя типа typedef, которое называет тип класса, или его версию с квалификацией cv, также является именем класса". Константа просто игнорируется.

  • Константа просто игнорируется. Субобъекты базового класса не могут быть константными сами по себе. 9.1/5 говорит: "Если имя typedef, которое называет класс класса с квалификацией, используется там, где требуется имя класса, cv-квалификаторы игнорируются".

Ответ 2

На самом деле это полный объект, который вы создаете, который является константой или не const, классы не имеют квалификации.

В using AC = A const; const просто игнорируется при использовании для наследования.