Несоответствие неоднозначности поиска имени
Я пытаюсь понять, почему эта программа не дает неоднозначность поиска имени для меня:
namespace X { int i = 1; }
namespace Q {
namespace P {
int i = 2;
using namespace X;
}
using namespace P;
int l = i;
}
int main() {}
Если мы изменим это так, мы получим неоднозначность поиска имени:
namespace X { int i = 1; }
namespace P {
int i = 2;
using namespace X;
}
using namespace P;
int l = i;
int main() {}
Единственное изменение, которое я сделал здесь, - это удалить пространство имен Q и поместить его содержимое в глобальное пространство имен.
Я пробовал с 3 разных компиляторов:
- GCC и Clang с http://melpon.org/wandbox
- Visual C++ с http://webcompiler.cloudapp.net/
Все дают результаты, указанные в этом письме, и я пытаюсь выяснить, почему.
Может кто-нибудь объяснить поведение с точки зрения стандарта C++? Я не понимаю этого.
1 ответ
В первой программе используется переменная i
определяется в пространстве имен P, потому что директива using
using namespace X;
размещает объявления X в глобальном пространстве имен (общее пространство имен для X и P). Таким образом, декларация i
в P (точнее в Q из-за другой директивы using) скрывает объявление X::i
в глобальном пространстве имен.
Из стандарта C++ (3.4.1 Безусловный поиск имени)
2 Объявления из пространства имен, назначенного директивой using, становятся видимыми в пространстве имен, включающем директиву using; см. 7.3.4.
Итак, мы имеем для первой программы
namespace X { int i = 1; }
namespace Q {
namespace P {
int i = 2;
using namespace X; // 1
}
using namespace P; // 2
int l = i;
}
что включающее пространство имен для использования директивы #1 является глобальным пространством имен, а включающее пространство имен для использования директивы #2 является пространством имен Q.
Во второй программе оба определения i
помещаются в глобальное пространство имен из-за этих двух директив using
//...
using namespace X;
//...
using namespace P;