Правила разрешения имен C++ для идентичных имен с другой областью видимости


Я понимаю, что это ужасный стиль, но для аргументации предположим, что у меня есть следующий код:

struct parent
{
   virtual ~parent() {}
};

struct child : public parent
{
   child() {}
   virtual ~child() {}
};

struct anotherClass
{
   static parent& anyName;
};

child anyName; // create an instance of 'child'
parent& anotherClass::anyName = anyName; // create a parent-class ref to the child object

Когда я инициализирую ссылку anotherClass::anyName выше с помощью anyName, с какой anyName я ее инициализирую? Объект дочернего класса или с самим собой? (К какой сущности относится последнее anyName в последней строке? Это двусмысленно?) И где в спецификации C++ будет рассматриваться нечто подобное?

(кстати этот вопрос не имеет абсолютно никакого отношения к моему другой вопрос , опубликованный несколькими минутами ранее.)

1 3

1 ответ:

С самим собой.

В отличие от вашего другого вопроса, этот можно решить с помощью небольшого образца кода. Я вставил код из вашего вопроса в онлайн-компилятор (clang)...

Http://rextester.com/EDW85421

Ответ компилятора довольно ясен:

Предупреждение: ссылка 'anyName' еще не привязана к значению, когда используется в собственной инициализации

(попробуйте закомментировать свою строку child anyName;; обратите внимание, что результат компиляции не меняется, потому что компилятор все равно не находил этот объект.)

Правила из стандарта C++, которые применяются в [basic.lookup.unqual]:

Имя, используемое в определении статического элемента данных класса X (после квалифицированного идентификатора статического элемента), ищется так, как если бы имя использовалось в функции-члене класса X.

И от [basic.scope.pdecl]

Точка объявления для имени находится сразу после его завершения. Декларатор и перед его инициализатором (если таковой имеется), за исключением случаев, указанных ниже.

Эти два правила вместе гарантируют, что неквалифицированный поиск инициализатора anyName находит anotherClass::anyName.