Стандартное соглашение для использования "std" - PullRequest
11 голосов
/ 25 декабря 2009

Точный дубликат: Вы предпочитаете явные пространства имен или "использование" в C ++?

Какой из них является предпочтительным соглашением для использования любого пространства имен?

using namespace std;

или

using std::cin;
using std::cout;

или

вызов функции как и когда требуется в коде?

std::cout<<"Hello World!"<<std::endl;

Ответы [ 9 ]

14 голосов
/ 25 декабря 2009

Очень хорошее объяснение дано здесь .

Первый стиль, то есть использование пространства имен независимо от того, что наносит ущерб всей цели пространства имен. Вы никогда не должны использовать его, за исключением небольших фрагментов кода. (Я там тоже не пользуюсь!: D)

Второй слишком многословен. Не практично.

Мне лично нравится третий стиль, т. Е. Ввод полного имени (например, std :: cout).

Помните, что код читается намного чаще, чем написано, и использование полностью определенных имен IMO делает ваш код более читабельным.

12 голосов
/ 25 декабря 2009

Об этом уже много раз спрашивали, но моя поисковая фу, кажется, на данный момент меня покинула. В основном:

  • Никогда не помещайте какую-либо директиву using в заголовочный файл & ndash; это приведет к заражению вашего кода и появлению всевозможных трудных для отслеживания ошибок.

  • Предпочитать объявление использования, например using std::string, в файле реализации (.cpp), который интенсивно использует такой тип.

  • В качестве крайней меры используйте using namespace std, но только в файлах реализации & ndash; Я использую его в сообщениях скомпилированного кода на SO, для удобства.

8 голосов
/ 25 декабря 2009

Это модифицированная версия другого ответа, который я написал на ту же тему. Достаточно этих вопросов, и, возможно, я получу окончательный пост;)

Основная проблема - конфликт имен, в том случае, если в вашем коде есть переменная cout, и вы using namespace std;, это будет неоднозначно относительно того, что вы имеете в виду. Это не просто cout. Также будут включены count, reverse и equal, которые являются общими идентификаторами.

Несмотря на все проблемы с компилятором, это также проблема для любого, кто придет читать ваш код. Эти дополнительные 5 символов гарантируют, что следующий человек, поддерживающий ваш код, точно знает, что вы имеете в виду.


Также стоит отметить, что вы никогда не должны ставить

using namespace std;

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

В большинстве случаев очень полезно использовать такие вещи, как

using std::swap

Как будто существует специализированная версия подкачки, компилятор будет использовать ее, иначе он вернется к std::swap. Если вы звоните std::swap, вы всегда используете базовую версию, которая не будет вызывать специализированную версию (даже если она существует).

Возьмем, к примеру, код с использованием pimpl idiom . Где в качестве копии по умолчанию можно скопировать все данные в фактической реализации, где все, что нужно сделать, это поменять местами указатели. Использование специализированного свопа может сэкономить огромное количество времени на выполнение, а хорошо спроектированные библиотеки должны специализировать его.


В итоге

  • Всегда предпочитайте using std::swap более std::swap()

  • Избегайте using namespace std в заголовке любой ценой из-за распространения, старайтесь не использовать его в файлах реализации.

  • Наличие тысяч using std::foo в начале каждого файла - не самый лучший способ. В большинстве случаев используйте его для обычных классов.

Все остальное - мнение.

3 голосов
/ 25 декабря 2009

Я лично предпочитаю третий вариант. Просто взгляните на это:

namespace A { int a=0; }
namespace B { int a=0; }

и вы используете его как:

using namespace A;
using namespace B;
using namespace std;

cout<<a<<endl; //error here!

Вместо этого, если бы вы могли просто сказать,

std::cout<<B::a<<std::endl; //No problem, more readable

Хотя для ввода кода может потребоваться немного больше времени, второй и третий варианты более предпочтительны.

1 голос
/ 26 декабря 2009

Я всегда перечисляю полное пространство имен. Это улучшает удобочитаемость и позволяет другим людям знать, откуда поступают ваши функции и данные. using очень раздражает при чтении кода других людей, особенно когда я пытаюсь чему-то научиться, потому что я не могу сказать, является ли это частью этого пространства имен или другим. И, как говорят другие разумные люди, это разрушает весь смысл пространства имен, не так ли? Суть в том, чтобы держать все отдельно и придавать смысл данным и логике.

Хороший порядок для запоминания: самый важный человек - клиент, который использует программу; второе по важности - это другие кодеры, которые либо поддерживают, либо пытаются учиться на вашем коде; наименее важен ты. : -)

1 голос
/ 25 декабря 2009

Я просто хотел бы отметить, что using namespace foo ограничен. Пример:

#include <iostream>
#include <vector>
//...
for (int i=0; i<10; ++i)
{
    using namespace std;
    cout << i << endl;
}
vector v; // won't compile

При осторожном использовании using namespace std может быть полезным и безвредным одновременно.

1 голос
/ 25 декабря 2009

Это вопрос стиля, но с одной стороны: вы никогда не должны импортировать пространство имен в глобальную область видимости. e.g.:

#include <iostream>
using namespace std; // Pollution!

int main()
{
    ....
}

Если вы хотите импортировать пространство имен, просто импортируйте его в область, в которой вы работаете:

#include <iostream>

int main()
{
    using namespace std; // Good!
    ....
}
0 голосов
/ 27 декабря 2009

Одно дело рекомендовать записывать полное имя, когда пространство имен равно std, где std :: добавляет только 5 дополнительных символов. Это совсем другая проблема, когда пространства имен складываются, и вы сталкиваетесь с необходимостью писать что-то вроде:

if (NumberOfInstances > 0 && (code_type == MyNamespace::MyLongButMeaningfulClassName::EnumDefinedWithinClass::CODE_GREEN ||
                              code_type == MyNamespace::MyLongButMeaningfulClassName::EnumDefinedWithinClass::CODE_YELLOW)) {

особенно, если у вас есть ограничивающие строки в стиле компании до 80 символов, и вы добавляете еще несколько отступов. Нечто подобное затмевает логику кода за всеми словами. В этот момент вы начинаете ценить использование псевдонимов и / или локальных пространств имен в интересах читабельности.

0 голосов
/ 25 декабря 2009

Все, что вы предпочитаете. На самом деле, это не имеет значения. Однако большинство фрагментов кода используют

using namespace std;
...