Я написал следующий код:
#include <iostream>
namespace A
{
int z=::b;
}
int b=5;
int main()
{
std::cout << A::z;
}
и я ожидал, что он будет работать правильно. Потому что:
Имя, предваряемое оператором унарной области :: (5.1), просматривается в глобальной области, в блоке перевода, где оно используется. Имя должно быть объявлено в глобальной области пространства имен или должно быть именем, декларация которого видна в глобальной области действия из-за директивы using (3.4.3.2). Использование :: позволяет ссылаться на глобальное имя, даже если его идентификатор был скрыт (3.3.10).
В этой цитате ничего не говорится о том, что переменная должна лексически объявляться перед использованием квалифицированного id.
Имя должно быть объявлено в глобальной области пространства имен
Вы должны написать:
int b=5;
namespace A
{
int z=::b;
}
От 3.3.2 Точка декларации:
Точка объявления для имени сразу же после его полного объявления (раздел 8) и перед его инициализатором (если есть), за исключением случаев, указанных ниже. [ Пример:
int x = 12; { int x = x; } Here the second x is initialized with its own (indeterminate) value. — end example ]
Это эффективно применяет объявление до использования в C++, за исключением исключений, таких как функции в области класса и т.д.