Пространство имен (using namespace std;)

Рейтинг: 35Ответов: 5Опубликовано: 11.04.2015

Очень часто в интернете вижу как многие программисты усердно пишут везде программы используя в коде std::. Зачем они это делают? Почему нельзя просто использовать using namespace std; перед программой, так же удобнее и код начинает "дышать". Или это плохой тон и стоит переучиваться на использование std:: непосредственно в коде программы?

Ответы

▲ 37Принят

Зависит от традиций. Среди плюсовиков традиция "лучше перестраховаться, чем получить внезапные трудно отлаживаемые проблемы неизвестно где".

Явное указание пространства имён — это избавление от потенциальных проблем в будущем. Положим, вы подключили через using namespace два пространства имён. Всё замечательно, кратко, красиво.

А потом вышла новая версия одной из библиотек, и какие-то идентификаторы стали резолвиться по-другому, например, во второй библиотеке добавили функцию, которая к вашим аргументам подходит лучше, чем используемая вами ранее функция из первой библиотеки.

В лучшем случае ваш код не соберётся. Может упасть. А может так получиться, что ваш код перестанет работать у клиента в 1% случаев. Всё может быть.

Отлавливать и исправлять подобные проблемы мучительно больно.

Насколько это важно конкретно для вас — решать вам. Если у вас простой проектик и от силы пара сторонних библиотек (или вообще только стандартная библиотека), то можно не заморачиваться с явным указанием пространств имён. Если проект огромный, с десятками библиотек, то может оказаться более удобным (и наглядным) всегда указывать пространства имён.

Банальный пример: положим, вы пользуетесь только стандартной библиотекой и boost, поэтому решили везде писать:

using namespace std;
using namespace boost;

...а теперь выходит новая версия стандартной библиотеки, в которой из boost перетащено много классов. И внезапно ваш код больше не компилируется.

В других языках другие традиции. Например, в C# почти всегда пишут краткие имена классов, и только в случае конфликтов явно указывают пространство имён или используют алиасы. Язык немного отличается: там нет функций вне классов. Это позволяет меньше терять читаемость и реже натыкаться на неожиданные конфликты.

▲ 10

В больших проектах, использующих множество сторонних библиотек, часто имеет смысл указывать пространство имён перед используемой конструкцией. Особенно, когда начинают пересекаться их имена. Ну и просто мгновенное понимание, откуда и что берётся - это большая экономия времени, нежели чем сложность прочтения слова из трёх букв. "std" имею в виду :)

▲ 7

В заголовочных файлах нужно всегда указывать пространство имён явно, поскольку никогда точно не знаешь, куда потом этот файл будет включён. Неожиданный using namespace std, привнесённый в код заголовочным файлом, может всё поломать.

Однако в cpp-файлах я всё время использую using namespace std. И сплю при этом совершенно спокойно. Никаких неожиданных проблем это никогда не вызывает.

Более того, даже в заголовочных файлах можно иногда использовать using namespace. Например, внутри тела шаблонной функции. Главное, следить за тем, чтобы эффект от объединения пространства имён не просочился за пределы той области, где он приносит ощутимую и видимую глазом пользу.

▲ 4

Вот что говорит Google Style Guide по этому поводу:

// Запрещено - Это загрязняет пространство имен.
using namespace foo;

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

// OK in .cc files.
// Must be in a function, method or class in .h files.
using ::foo::bar;

Я бы не стал не доверять рекомендациям этих ребят, они пишут огромный проект Chromium.

▲ 3

"Засорять" текущее пространство имен - плохой тон, используйте лишь то, что вам нужно. Например, так:

using std::string;
using std::cin;
using std::cout;
using std::endl;
using std::swap;
и т.д.