Какова цель "использования пространства имен"?
Есть убедительные аргументы против 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/