Ответ 1
Код стандартно совместим и был с С++ 11, но не был на С++ 03.
С++ 11 - С++ 17 говорят об этом во введении к разделу [class.access], Access Access Control:
Все элементы управления доступом в разделе [class.access] влияют на возможность доступа к имени члена класса из объявления конкретного объекта, включая части объявления, предшествующие имени объявляемого объекта, и, если объект является классом, определения членов класса, выходящих за пределы спецификации класса.
В тех же стандартных версиях приведен пример, который очень похож на ваш вопрос, но даже немного сложнее:
[Пример:
class A { ... protected: struct B { }; }; ... struct D: A::B, A { };
... Использование
A::B
в качестве базового-спецификатора хорошо сформировано, потому чтоD
является производным отA
, поэтому проверка базовых спецификаторов должна быть отложена до тех пор, пока не будет замечен весь список-спецификатор базы. -end пример]
Но я вижу те же результаты: g++ и clan g++ оба отклоняют эти программы, независимо от того, что -std=
аргумент, который я даю. Это пара ошибок компилятора.
С++ 03 имеет это вместо первого абзаца I, приведенного выше:
Все элементы управления доступом в разделе [class.access] влияют на возможность доступа к имени члена класса из определенной области. Контроль доступа для имен, используемых в определении члена класса, который появляется за пределами определения класса участника, выполняется так, как если бы определение всего члена появилось в области класса-члена...
Базовый-спецификатор определения класса не входит в эту область класса, поэтому С++ 03 не позволяет использовать защищенное или приватное имя в качестве имени базового класса для производного класса, который в противном случае имеет доступ к этому имени.