Начнем с другого примера.
const int x = 10;
namespace e {
const int y = 5;
}
int main()
{
std::cout << e::y;
using namespace e;
std::cout << y;
}
Существует переменная со значением 10 и именем x
в глобальном пространстве имен (которое можно просто назвать x
) и переменная со значением 5 с именем y
в пространстве имен e
(которое должно называться e::y
).
Добавляя using namespace e;
, вы вставляете все имена из пространства имен e
в глобальное пространство имен. Это означает, что глобальное пространство имен теперь содержит имена x
и y
, а пространство имен e
содержит имя y
. Теперь вы можете ссылаться на переменную со значением 5
, используя как y
, так и e::y
.
Теперь вернемся к вашему примеру. Если мы изменим y
на x
:
const int x = 10;
namespace e {
const int x = 5;
}
int main()
{
std::cout << e::x;
using namespace e;
std::cout << x;
}
В глобальном пространстве имен есть x
, а в пространстве имен e
— x
. Добавляя using namespace e;
, вы вводите все имена из пространства имен e
в глобальное пространство имен, так что теперь глобальное пространство имен содержит имена x
и x
, а пространство имен e
содержит имя x
. Видите проблему? Глобальное пространство имен содержит два имени x
, что сбивает с толку компилятор. Когда вы пытаетесь вывести переменную под именем x
, компилятор ищет имена в глобальном пространстве имен и находит два x
. Он не может выбрать, какой из них вы имели в виду, поэтому выдает ошибку.
Это основная причина, по которой using namespace
(особенно using namespace std;
) считается злом а>. Можно легко сломать работающий код, обновив библиотеку или внедрив новую функцию. Ошибка компилятора - лучший выход в таком случае, но иногда возможно, что компилятор молча заменит одну функцию на другую, потому что она лучше соответствует.
Вы по-прежнему можете получить доступ к обеим переменным, используя полные имена:
int main()
{
using namespace e;
std::cout << ::x << " "; //x from global with fully quafilied name
std::cout << ::e::x << " "; //x from namespace e with fully qualified name
std::cout << e::x; //not fully qualified, but not ambiguous either - only one x in namespace e
}
person
Yksisarvinen
schedule
14.01.2021
using namespace e;
, как компилятор может различать::x
и::e::x
? - person Yksisarvinen   schedule 14.01.2021