Использование «using» в файлах заголовков

#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
  

Просто подумал, что вы могли бы найти это полезным, если вы действительно хотите иметь возможность определять что-то (например, класс), не записывая определенный префикс пространства имен все время.