Существуют убедительные аргументы против 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
.
Кстати, использование объявления/директивы не противоречит цели пространств имен, поскольку вы всегда можете полностью уточнить имя в случае неоднозначности.
В большинстве случаев это просто ярлык для написания кода. Вы можете импортировать имена в окружающий контекст. Обычно я ограничиваю его .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
(моя компания, Gregory Consulting, предшествует std::string
). Использование пространств имен (с ключевым словом using
или без него) позволяет всем нам писать более чистый и аккуратный код. Но когда вам приходится говорить Gregcons::string
каждый раз, вы как бы теряете более чистую и аккуратную часть. [Отказ от ответственности: на самом деле я больше не использую свой собственный строковый класс — представьте какой-нибудь подходящий конфликт имен.] В этом привлекательность оператора using
. Держите его подальше от заголовков, не применяйте его к std
, и вообще у вас не должно быть проблем.
using namespace foo
, а using foo::whatever
; это относится как к стандартным, так и к другим именам. Например, нет ничего плохого в using std::cout
, если это не сделано в заголовке.
- person celtschk; 15.07.2013
Я нахожу это полезным при работе с библиотеками с глубоко вложенными пространствами имен. Библиотека Boost является одним из таких примеров. Представляю, как везде печатают boost::numeric::ublas::matrix<double> m
...
Чего следует избегать, так это делать using namespace
в заголовочном файле, так как это может сильно испортить любую программу, которая включает указанный заголовок. Всегда размещайте операторы using namespace
в файлах .cpp/.cxx, чтобы они ограничивались областью действия файла.
matrix
.
- person jalf; 06.12.2010
typedef boost::numeric::ublas::matrix<double> DoubleMatrix
и используйте DoubleMatrix
в остальной части кода. В этом красота/проклятие C++: есть несколько подходов к решению одной и той же проблемы.
- person CadentOrange; 06.12.2010
«Пространства имен позволяют группировать сущности, такие как классы, объекты и функции, под именем. Таким образом, глобальная область может быть разделена на «подобласти», каждая из которых имеет свое собственное имя. Где идентификатор — это любой допустимый идентификатор, а сущности — это набор классы, объекты и функции, включенные в пространство имен"
Дополнительная информация здесь: http://www.cplusplus.com/doc/tutorial/namespaces/ а>
#include <iostream.h>
, тоcin
иcout
прекрасно работают без квалификацииstd::
. Так что миграция кода для меня точно не аргумент. - person fredoverflow   schedule 05.12.2010using std::swap;
описан в этот ответ to Что требует от меня объявить использование пространства имен std? (Существенно ли этот вопрос отличается от того вопроса? Я не знаю, является ли это точной копией, но они, похоже, охватывают одну и ту же тему .) - person James McNellis   schedule 05.12.2010