Как интерпретировать правило [namespace.udir]p2 в стандарте С++?

Меня немного смущают последствия [namespace.udir]p2. Рассмотрим следующую программу:

namespace X { int i = 1; }

namespace Y { using namespace X; }

int main() { i = 2; }

В нем поиск имени для i в main не работает (я пробовал с GCC, Clang и Visual C++). Похоже, это не согласуется с [namespace.udir]p2 (http://eel.is/c++draft/dcl.dcl#namespace.udir-2):

Директива-использования указывает, что имена в назначенном пространстве имен могут использоваться в той области, в которой директива-использования появляется после директивы-использования. Во время поиска неполного имени ([basic.lookup.unqual]) имена отображаются так, как если бы они были объявлены в ближайшем охватывающем пространстве имен, которое содержит как директиву использования, так и назначенное пространство имен. [Примечание: In В данном контексте «содержит» означает «содержит прямо или косвенно». — примечание в конце]

В моей программе я применяю это правило для имени i, объявленного int i = 1; в X, следующим образом:

  • Директива использования: using namespace X;

  • Назначенное пространство имен: X

  • Ближайшее окружающее пространство имен: глобальное пространство имен.

Разве это не означает, что неквалифицированный поиск имени i в main должен найти X::i? Почему я не получаю такого результата ни с одним из трех испробованных компиляторов?


person Supremum    schedule 18.07.2015    source источник
comment
имена отображаются так, как если бы они были объявлены применяется только к неквалифицированному поиску в Y. Это то, о чем говорится в первом предложении, имена в назначенном пространстве имен могут использоваться в той области, в которой появляется директива использования   -  person dyp    schedule 18.07.2015


Ответы (1)


Использование-директивы делает имена видимыми в той области, в которой они появляются. Например, [basic.scope.namespace]p1

для каждой директивы-использования, определяющей пространство имен члена, потенциальная область действия члена включает ту часть потенциальной области действия директивы-использования, которая следует за точкой объявления члена.

где область действия имени — это часть программы, в которой это имя (объявление этого имени) можно найти с помощью неполного поиска.

Точно так же в [namespace.udir]p2,

Директива-использования указывает, что имена в назначенном пространстве имен могут использоваться в области, в которой директива-использования появляется после директивы-использования.

что в основном говорит о том же, что и приведенная выше цитата.

В OP директива использования появляется в пространстве имен пространства имен Y; main находится за пределами этой области, поэтому директива использования не влияет на поиск имени, выполняемый внутри main.

person dyp    schedule 18.07.2015
comment
К сожалению, здесь термин «область действия» используется двумя разными способами; область имени (как определено в моем ответе) и область пространства имен (часть программы, где вы можете объявить имя, имеющее область пространства имен, но ссылаясь на единое пространство имен). - person dyp; 18.07.2015
comment
Да, стандарт иногда путает область действия с декларативной областью. По этому поводу существует проблема стандартного основного языка С++. См.: stackoverflow. ком/вопросы/23630201/ - person Supremum; 19.07.2015