Ответ 1
Это определение
struct A {
struct B;
};
Определяет struct A
с объявлением вложенной структуры B
1. Полноценное имя B
равно A::B
, вы можете сказать, что B
находится внутри "пространства имен" A
. Тогда это:
struct A::B : A { // Note I added spaces
};
Является ли определение A::B
, а единственный :
указывает, что он получен из A
.
Теперь интересная часть A::B::A::B
. Разрежьте его:
-
A::B
обозначает вложенную структуру. -
A::B::A
получает доступ к имени введенного классаA
внутриB
. Инъекция связана с наследованием. -
A::B::A::B
снова введет вложенную структуруB
вA
.
И вы можете продолжить ad-infinitum или, по крайней мере, до тех пор, пока ваш компилятор не выполнит свой лимит перевода 2.
Увлекательное интеллектуальное упражнение, но избегайте, как чума в реальном коде.
[class.qual]/1 объясняет, как работает поиск
Если спецификатор вложенного имени квалифицированного идентификатора назначает класс, имя, указанное после определения вложенного имени-спецификатора в объем класса ([class.member.lookup]), за исключением случаев перечислено ниже. Название должно представлять один или несколько членов этого класса или одного из его базовых классов (раздел [class.derived]).
И вышеприведенный текст позволяет нам назвать базовый класс, потому что [class]/2
Имя класса также вставляется в область самого класса; это известно как имя введенного класса. Для доступа проверка, имя введенного класса обрабатывается так, как если бы оно было общедоступным имя участника.
Вышеприведенное ясно говорит о том, что при запуске полного имени с A::
вы можете указать член или базовый класс. Поскольку A
не имеет оснований, вы можете указать только A::B
( "тип члена" ). Но A::B
также назначает класс. Поэтому мы можем указать базу или ее часть с помощью A::B::
, что позволяет нам называть A::B::A
. Теперь промойте и повторите.
<суб > 1 - Обратите внимание на это совсем другое B
. Совсем не связано с глобальным struct B
.
2 - рекомендуемый минимум 256 в соответствии с [implimits]/2.36
суб >