#c #namespaces #using
#c #пространства имен #использование
Вопрос:
Я понял, что мне не следует использовать это в заголовочном файле:
using namespace foo;
Потому что это выводит пространство имен foo в глобальную область видимости для всех, кто использует мой файл заголовков.
Могу ли я предотвратить это, если я сделаю это в своем собственном пространстве имен? Например, так:
namespace my_lib
{
using namespace foo;
// my stuff
// ...
}
Теперь использующее пространство имен foo должно быть ограничено областью пространства имен my_lib, верно?
Комментарии:
1. Имейте в виду, что это перетаскивает все содержимое пространства имен
foo
в пространство именmy_lib
. Это действительно то, чего вы хотите для своих пользователей? Это может быть лучше, чем загрязнять глобальное пространство имен, но вы все равно загрязняете пространство имен…2. Вы просто хотите сократить пространство имен? вместо того, что
foo::bar::box::action()
вы хотитеmy_lib::action()
в этой ситуации, вам нужен псевдоним пространства именnamespace my_lib = foo::bar::box;
Ответ №1:
ДА. Это лучше, чем использовать using namespace foo
на глобальном уровне.
Все же лучше было бы, если бы вы использовали foo::name
синтаксис.
Теперь использующее пространство имен foo должно быть ограничено областью пространства имен my_lib, верно?
ДА. Он переносит все имена из пространства имен foo
в пространство имен my_lib
, что может вызвать конфликты имен в my_lib
. Вот почему foo::name
это наиболее предпочтительный подход.
Комментарии:
1. Я не согласен с тем, что всегда уместно использовать полное имя пространства имен. Наложение псевдонимов и приведение имен в областях значительно упрощает код. Если пользователям
my_lib
почти всегда также нужно использоватьfoo
, имеет смысл объединить их область действия.2. @edA-qa морт-ора-й: Что делать, если возникают коллизии имен? Кроме того,
my_lib
может ссылаться на другие имена из дюжины других пространств имен, значит ли это, что оно должно использоватьсяusing namespace xyz
для всех пространств имен?3. Я также выступаю за включение имен в область видимости, когда это облегчает чтение результирующего кода. Однако существуют способы достижения этого, которые не имеют каких-либо серьезных недостатков (например, см. Ниже).
4. коллизии всегда возможны, но я не вижу никаких причин, по которым их возможность должна препятствовать импорту имен. Если одно пространство имен предназначено для наслоения на другое, вам просто нужно избегать столкновений. Если два пространства имен совершенно не связаны, то импорт имен, вероятно, не следует выполнять.
5. @edA-qa mort-ora-y: Ваш комментарий на самом деле не затрагивает проблемы коллизий имен. Как я уже сказал, что, если возникнут конфликты имен? Кроме того, включение нескольких имен, которые также включают функции, в область видимости может создать проблему ADL и другого поиска имен, что может привести к непреднамеренному разрешению функций и так далее!
Ответ №2:
Да, если вы сделаете это, то это просто перенесет все имена из foo
в my_lib
, что, как указывали другие, может быть желательным, а может и не быть.
Одна вещь, которую я хотел бы отметить в дополнение к тому, что говорили другие, заключается в том, что вы можете использовать идею «using directive в пространстве имен» как способ имитации директивы using, которая ограничена областью видимости класса. Обратите внимание, что это незаконно:
class C
{
using namespace boost; // for example
// ...
};
Но вы можете сделать это вместо этого:
namespace C_Namespace {
using namespace boost;
class C
{
};
}
using C_Namespace::C; // bring C itself back into the global namespace
Просто подумал, что вы могли бы найти это полезным, если вы действительно хотите иметь возможность определять что-то (например, класс), не записывая определенный префикс пространства имен все время.