Какова цель "использования пространства имен"?

Есть убедительные аргументы против using namespace stdтак почему он вообще был введен в язык? не using namespace победить цель пространства имен? Зачем мне когда-нибудь писать using namespace? Есть ли проблема, о которой я не знаю, которая элегантно решается using namespaceможет быть, в соответствии с using std::swap идиома или что-то в этом роде?

6 ответов

Решение

С одной стороны, это способ использовать перегрузки операторов в пространстве имен (например, using namespace std::rel_ops; или же using namespace boost::assign;)

Краткость также сильный аргумент. Вы действительно любите печатать и читать std::placeholders::_1 вместо _1? Кроме того, когда вы пишете код в функциональном стиле, вы будете использовать множество объектов в std а также boost Пространство имен.

Другое важное использование (хотя обычно не импортируются целые пространства имен) - включение поиска, зависящего от аргументов:

template <class T>
void smart_swap(T& a, T& b)
{
    using std::swap;
    swap(a, b);
}

Если swap перегружен для некоторого типа T в том же пространстве имен, что и T, будет использоваться эта перегрузка. Если вы явно назвали std::swap вместо этого эта перегрузка не будет рассматриваться. Для других типов это возвращается к std::swap,

Кстати, декларация / директива using не противоречит цели использования пространств имен, поскольку вы всегда можете полностью определить имя в случае двусмысленности.

В большинстве случаев это просто ярлык для написания кода. Вы можете импортировать имена в свой контекст. Я обычно ограничиваю это .cpp файлы, потому что, когда вы включаете директиву using в .h файл, он загрязняет все файлы, в которые он включен. Еще одной хорошей практикой является ограничение using namespace к наиболее закрытой среде, возможной, например, внутри объявления тела метода. Я рассматриваю это как удобство, больше не похожее на псевдонимы пространства имен, такие как:

namespace po = boost::program_options;

и тогда вы можете написать

po::variables_map ...

Основная причина, почему using namespace была представлена ​​обратная совместимость: если у вас есть много кода перед пространством имен, использующего множество (предварительно стандартных версий) стандартных библиотечных функций и классов, вам нужен простой способ заставить этот код работать со стандартным компилятором, соответствующим требованиям.

Кстати, зависящие от аргумента правила поиска по крайней мере для C++98 означают, что using namespace std::rel_ops не будет делать то, что вы хотите в шаблонах (я не знаю, изменилось ли это в более поздней версии стандарта).

Пример:

template<typename T> bool bar(T t)
{
  return t > T();
}

namespace foo
{
  class X {};
  bool operator<(X, X);
}

using namespace std::rel_ops;

int main()
{
  X x;
  bar(x); // won't work: X does not have operator>
}

Обратите внимание, что положить using namespace в namespace foo тоже не поможет

Однако, использование объявлений в правильном месте помогает:

template<typename T> bool bar(T t)
{
  return t > T();
}

namespace foo
{
  class X {};
  bool operator<(X, X);
  using std::rel_ops::operator>;
}

int main()
{
  X x;
  bar(x); // now works: operator> found per ADL via the using declaration in `namespace foo`
}

Люди специально возражают против using namespace std; но не для using namespace BigCorp; или со ссылкой на std::cout (который использует пространство имен, просто не using это, если вы знаете, что я имею в виду.) Кроме того, большинство возражений против using namespace std находятся в заголовочном файле. В исходном файле, где можно сразу увидеть эффекты, это менее вредно.

Пространства имен - это невероятно полезная концепция, которая позволяет мне иметь класс с именем Date, хотя в библиотеке, которую я использую, есть класс с именем Date. Прежде чем они были добавлены к языку, мы должны были иметь такие вещи, как GCDate а также GCString (моя компания, Грегори Консалтинг, предшествовала std::string). Использование пространств имен (с или без using Ключевое слово) позволяет всем нам писать чище, аккуратнее код. Но когда ты должен сказать Gregcons::string каждый раз вы теряете чистую, аккуратную часть. [Отказ от ответственности: на самом деле я больше не использую свой собственный класс строк - представьте себе какой-то подходящий конфликт имен.] Это привлекательность using заявление. Держите его подальше от заголовков, не применяйте его к stdи вы должны вообще избегать неприятностей.

Я считаю это полезным при работе с библиотеками с глубоко вложенными пространствами имен. Библиотека Boost является одним из таких примеров. Печать изображений boost::numeric::ublas::matrix<double> m повсюду...

То, что нужно избегать, это делать using namespace в файле заголовка, так как он может по-королевски испортить любую программу, которая включает в себя указанный заголовок. Всегда место using namespace операторы в файлах.cpp/.cxx, так что это ограничено областью действия файла.

"Пространства имен позволяют группировать сущности, такие как классы, объекты и функции, по имени. Таким образом, глобальную область можно разделить на" подобласти ", каждая со своим именем. Где идентификатор - это любой действительный идентификатор, а сущности - это набор классы, объекты и функции, которые включены в пространство имен "

Более подробная информация здесь: http://www.cplusplus.com/doc/tutorial/namespaces/

Другие вопросы по тегам