Есть убедительные аргументы против using namespace std
, так почему он был введен в язык вообще? Не побеждает ли using namespace
цель пространств имен? Зачем мне писать using namespace
? Есть ли какие-либо проблемы, о которых я не знаю, это элегантно решается using namespace
, может быть, в строках идиомы using std::swap
или что-то в этом роде?
Какова цель: "использование пространства имен"?
Ответ 1
Во-первых, это способ использования перегрузок операторов в пространстве имен (например, 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
.
BTW, использование декларации/директивы не отменяет цели пространств имен, так как вы всегда можете полностью квалифицировать имя в случае двусмысленности.
Ответ 2
В большинстве случаев это просто ярлык для написания кода. Вы можете импортировать имена в свой контекст. Обычно я ограничиваю его .cpp
файлами, потому что когда вы включаете директиву using в файл .h
, он загрязняет все файлы, в которые он включен. Другая хорошая практика ограничивает using namespace
наиболее благоприятную окружающую среду, например, внутри декларации тела метода. Я рассматриваю это как удобство, не более и подобное псевдониму пространства имен, например:
namespace po = boost::program_options;
а затем вы можете написать
po::variables_map ...
Ответ 3
Основная причина, по которой была введена using namespace
, была обратная совместимость: если у вас много кода перед пространством имен с использованием множества стандартных функций библиотеки и классов, вам нужен простой способ сделать этот код работать со стандартным соответствующим компилятором.
BTW, зависящие от аргумента правила поиска, по крайней мере для С++ 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`
}
Ответ 4
Люди специально возражают против using namespace std;
, но не до using namespace BigCorp
; или ссылаться на std::cout
(который использует пространство имен, а не using
его, если вы знаете, что я имею в виду.) Кроме того, большинство возражений на using namespace std
находятся в файле заголовка. В исходном файле, где эффекты можно сразу увидеть, это менее вредно.
Пространства имен - невероятно полезная концепция, которая позволяет мне иметь класс под названием Date, даже если библиотека, которую я использую, имеет класс Date. Прежде чем они были добавлены к языку, нам пришлось иметь такие вещи, как GCDate
и GCString
(моя компания, Грегори Консалтинг, предшествовала std::string
). Использование пространств имен (с ключевым словом using
или без него) позволяет нам писать более чистый, более чистый код. Но когда вы должны каждый раз говорить Gregcons::string
, вы теряете чистую, более аккуратную часть. [Отказ от ответственности: я больше не использую свой собственный класс строк - представьте себе подходящий конфликт имен.] Это обращение к выражению using
. Держите его вне заголовков, не применяйте его к std
, и вы, как правило, не должны беспокоиться.
Ответ 5
Я считаю это полезным при работе с библиотеками с глубоко вложенными пространствами имен. Одним из таких примеров является библиотека Boost. Печать изображений boost::numeric::ublas::matrix<double> m
повсюду...
Вещь, которую следует избегать, делает using namespace
в заголовочном файле, так как это потенциально может привести к зависанию любой программы, содержащей указанный заголовок. Всегда размещайте операторы using namespace
в файлах .cpp/.cxx, чтобы они ограничивались областью файлов.
Ответ 6
"Пространства имен позволяют группировать объекты, такие как классы, объекты и функции под именем. Таким образом, глобальная область видимости может быть разделена на" под-области ", каждая из которых имеет собственное имя. Где идентификатор - любой действительный идентификатор, а сущности - набор классов, объектов и функций, включенных в пространство имен"
Дополнительная информация здесь: http://www.cplusplus.com/doc/tutorial/namespaces/