Безымянные правила доступа к пространству имен
Я просматривал раздел 7.3.1.1 в стандарте C++03, ожидая найти некоторое описание правил доступа для элементов, определенных в безымянном пространстве имен.
Правила кажутся немного другими для безымянных пространств имен, так как вы не можете полностью определить доступ к элементам в одном. Я знаю, что, по крайней мере, в одном и том же модуле перевода можно получить доступ к элементам в безымянном пространстве имен, как если бы они не были в пространстве имен. Например:
namespace {
int foo;
}
void something()
{
foo = 4;
}
Если у пространства имен есть имя, вы не сможете этого сделать. Итак, где же правила, определенные в стандарте для этих исключительных правил, которые применяются к безымянным пространствам имен?
2 ответа
Анонимное пространство имен в основном рассматривается как:
namespace unique_per_TU
{
// Stuff
}
using namespace unique_per_TU;
Я постараюсь найти ссылку здесь через минуту.
РЕДАКТИРОВАТЬ:
Похоже, вы уже нашли его в 7.3.1.1/1
Безымянное определение пространства имен ведет себя так, как если бы оно было заменено
namespace unique { /* empty body */ }
using namespace unique;
namespace unique { namespacebody }
где все вхождения уникальности в единице перевода заменены одним и тем же идентификатором, и этот идентификатор отличается от всех других идентификаторов во всей программе.
"Поддельное" использование уже приводит членов пространства имен в глобальное пространство имен, как вы обнаружили.
Помимо стандартной цитаты, которая определяет Безымянные пространства имен в 7.3.1.1/1,
Это явно указано в одном из примеров в
3.3.5/1 Область пространства имен:
Декларативная область определения пространства имен является его телом пространства имен. Потенциальная область, обозначаемая исходным именем пространства имен, представляет собой объединение декларативных областей, установленных каждым из определений пространства имен в одной и той же декларативной области с этим исходным именем пространства имен. Объекты, объявленные в теле пространства имен, называются членами пространства имен, а имена, введенные этими объявлениями в декларативную область пространства имен, называются именами членов пространства имен. Имя члена пространства имен имеет область имен. Его потенциальная область действия включает в себя пространство имен от точки объявления имени (3.3.1) и далее; и для каждой директивы using (7.3.4), которая назначает пространство имен члена, потенциальная область действия члена включает ту часть потенциальной области действия директивы using, которая следует за точкой декларации члена.
>[Example:
namespace N {
int i;
int g(int a) { return a; }
int j();
void q();
}
namespace { int l=1; }
// the potential scope of l is from its point of declaration
// to the end of the translation unit
namespace N {
int g(char a) // overloadsN::g(int)
{
return l+a; // l is from unnamed namespace
}
int i; // error: duplicate definition
int j(); // OK: duplicate function declaration
int j() // OK: definition ofN::j()
{
return g(i); // callsN::g(int)
}
int q(); // error: different return type
}
- конец примера]
Обратите внимание на формулировки:
потенциальный объем l
от его декларации до конца блока перевода