Анонимная Неопределенность Пространства Имен
Рассмотрим следующий фрагмент:
void Foo() // 1
{
}
namespace
{
void Foo() // 2
{
}
}
int main()
{
Foo(); // Ambiguous.
::Foo(); // Calls the Foo in the global namespace (Foo #1).
// I'm trying to call the `Foo` that's defined in the anonymous namespace (Foo #2).
}
Как я могу сослаться на что-то внутри анонимного пространства имен в этом случае?
5 ответов
Ты не можешь Стандарт содержит следующий раздел (§7.3.1.1, C++ 03):
Определение безымянного пространства имен ведет себя так, как если бы оно было заменено
namespace unique { /* empty body */ }
using namespace unique;
namespace unique { namespace-body }
где все вхождения уникальности в единице перевода заменены одним и тем же идентификатором, и этот идентификатор отличается от всех других идентификаторов во всей программе.
Таким образом, вы не можете ссылаться на это уникальное имя.
Однако вы могли бы технически использовать что-то вроде следующего:
int i;
namespace helper {
namespace {
int i;
int j;
}
}
using namespace helper;
void f() {
j++; // works
i++; // still ambigous
::i++; // access to global namespace
helper::i++; // access to unnamed namespace
}
В то время как Георг дает стандартный, правильный, правильный и респектабельный ответ, я хотел бы предложить свой хакерский - использовать другое пространство имен в анонимном пространстве имен:
#include <iostream>
using namespace std;
namespace
{
namespace inner
{
int cout = 42;
}
}
int main()
{
cout << inner::cout << endl;
return 0;
}
Единственное решение, которое я могу придумать, это не изменяет существующее расположение пространства имен, это делегировать main
к функции в анонимном пространстве имен. (main
сама по себе должна быть глобальной функцией (§3.6.1/1), поэтому она не может находиться в анонимном пространстве имен.)
void Foo() // 1
{
}
namespace
{
void Foo() // 2
{
}
}
namespace { // re-open same anonymous namespace
int do_main()
{
Foo(); // Calls local, anonymous namespace (Foo #2).
::Foo(); // Calls the Foo in the global namespace (Foo #1).
return 0; // return not optional
}
}
int main() {
return do_main();
}
Единственный реальный способ - поместить код, к которому вы хотите получить доступ, в это пространство имен. В противном случае нет способа разрешить безымянное пространство имен, так как у него нет идентификатора, который вы можете дать, чтобы решить неоднозначную проблему разрешения.
Если ваш код находится внутри самого блока пространства имен {}, локальное имя получает приоритет над глобальным, поэтому Foo() вызовет Foo() в вашем пространстве имен, а::Foo() вызовет пространство имен в глобальном объем.