Сначала посмотрите на этот упрощенный код (и мое упрощенное объяснение, вы можете прочитать §3.4.3.2 для деталей):
namespace a
{
int x;
}
int main()
{
int i = a::x;
}
Подумайте, что происходит, когда мы говорим a::x
. Сначала компилятор перечисляет все объявления x
в a
. Если он находит однозначный x
, он успешно завершается. В противном случае он рекурсивно ищет пространства имен, объявленные директивой using. Если результат так и не найден, программа некорректна.
namespace a
{
int x;
}
namespace b
{
using namespace a;
}
int main()
{
int i = b::x;
}
Здесь он не находит x
в b
, поэтому он ищет пространство имен a
(из-за директивы using) и находит его. Теперь должно иметь смысл, почему это не является двусмысленным:
namespace a
{
int x;
}
namespace b
{
using namespace a;
int x;
}
int main()
{
int i = b::x;
}
Здесь он находит x
в b
и никогда не рассматривает a
. Теперь просто учтите, что безымянное пространство имен - это просто пространство имен с уникальным неизвестным именем:
namespace b
{
namespace
{
int x;
}
// this is what an unnamed namespace expands to (in exposition)
namespace __unique__ {}
using namespace __unique__;
namespace __unique__
{
int x;
}
int x;
}
int main()
{
int i = b::x;
}
Как и прежде, x
в b
находится без учета безымянного пространства имен. Ваш код похож.