Код: Выделить всё
namespace NA {
int foo(Zoo::Lion);
}
namespace NB {
int foo(Zoo::Lion);
namespace NC {
namespace N1 {
int foo(Zoo::Cat);
}
namespace N2 {
int test() {
using namespace N1;
using namespace NA;
return foo(Zoo::Lion());
}
}
}
}
Причина в том, что использование пространства имен NA не дает t фактически перенести имена из NA в область текущую; он помещает их в область наименьшего общего предка NA и N2, то есть ::. А использование пространства имен N1 не переносит имена из N1 в область текущую; он помещает их в наименее общую область предков N1 и N2, то есть NC. Вот я нарисовал красивую диаграмму:

Затем обычный неквалифицированный поиск «просматривает» дерево в порядке проверки–
Код: Выделить всё
N2–NC–NB–::Думаю, я достаточно хорошо понимаю этот механизм, чтобы объяснить, как он работает. Чего я не понимаю, так это почему. Когда разрабатывались пространства имен C++, почему они выбрали этот совершенно странный механизм вместо чего-то более простого, например «Имена переносятся в текущую область точно так же, как с помощью using-declaration» или «Имена переносятся в глобальную область видимости» или «Имена остаются там, где они есть, в каждом «используемом» пространстве имен выполняются отдельные поиски, а затем объединяются»?
Какие соображения учитывались при выборе этого конкретного механизма для C++?
Я специально ищу ссылки на дизайн C++ — книги, сообщения в блогах, документы WG21, D&E , ARM, обсуждение отражателя, что-то в этом роде. Я специально не ищу ответы, «основанные на мнениях»; Я ищу настоящее обоснование, указанное во время разработки этой функции.
(Я читал Дизайн и эволюция C++ (1994), раздел 17.4 «Пространства имен», но там даже не упоминается этот дурацкий механизм. D&E говорит: «директива using не вводит имена в файл. локальная область видимости; он просто делает доступными имена из пространства имен». Это правда, но лишено логического обоснования; я надеюсь, что Stack Overflow справится с этим лучше.)
Подробнее здесь: https://stackoverflow.com/questions/653 ... ay-it-does