2009-12-25 3 views
11

Точный дубликат:Do you prefer explicit namespaces or ‘using’ in C++?Стандартная конвенция для использования «СТД»

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

using namespace std; 

или

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

или

вызова функции, как и в случае необходимости в коде?

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

не используйте второе соглашение, вы потеряете свое здравомыслие. –

+7

Второе соглашение, конечно, правильно использовать. – 2009-12-25 17:43:50

+1

Второй или третий в зависимости от контекста. Первый должен использоваться только для учебника «Hello World» или быстрых демонстраций. –

ответ

14

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

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

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

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

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

+6

Цель любой концепции в программировании - облегчить жизнь программистам. Если вы сильно используете стандартную библиотеку, «используя» что-то может сделать ваш код более кратким. Как используется 'std :: string; string a; строка b; строка c; string d' более подробный, чем 'std :: string a; std :: string b; std :: string c; std :: string d; '? Если вам нужно много использовать, полное имя становится громоздким. И серьезно, кто будет ручным катанием собственного класса 'string', когда уже есть' std :: string'? Если вы говорите 'string x' 95% времени, это' std :: string', и все это знают. –

+0

Это одно исключение. Что делать, если вы говорите «используя std :: count», а затем нужно определить функцию или переменную с тем же именем? – missingfaktor

+6

Не согласен: я не вижу проблем с 'using namespace std;' в исходном файле. Но НИКОГДА не используйте # 1 или # 2 в файле заголовка. – rlbond

-4

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

using namespace std; 
+2

... и это побеждает всю цель пространства имен. – missingfaktor

+3

Это объясняется тем, что большинство фрагментов кода являются небольшими и предназначены для максимальной читаемости. Производственный код разработан для максимальной надежности, во-вторых, удобочитаемости. Вытягивание всего пространства имен сделает написанный код хрупким, особенно если вы поместите его в файл заголовка. – Steve

+2

snippets! = Real code – rlbond

12

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

  • Никогда не помещайте с помощью директивы любого рода в заголовочном файле – делает так будет загрязнять ваш код и ввести все виды трудно отследить ошибки.

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

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

+0

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

+2

Что такое "маленький"? Я не пишу гигантских классов, но я также не сохраняю каждое имя в стандартной библиотеке C++ в моей голове. Явное указание имен, которые я обычно использую, позволяет избежать неприятных (и очень, очень трудных для отладки) проблем. – 2009-12-25 18:00:00

+0

Хотя ADL может обойти ваши лучшие планы, чтобы не загрязнять ваш контекст именами стандартных функций.'#include #include int main() {std :: vector foo; std :: vector bar; copy (foo.begin(), foo.end(), bar.begin()); } '. Если вы планируете использовать имя «copy» для чего-то еще, лучше всего убедитесь, что вы случайно не вызывали свою версию, если это означало перегрузку, обнаруженную ADL, или наоборот. –

1

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

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

int main() 
{ 
    .... 
} 

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

#include <iostream> 

int main() 
{ 
    using namespace std; // Good! 
    .... 
} 
+0

Не совсем. Это зависит от вашей программы (насколько она велика, насколько она использует стандартную библиотеку и т. Д.). –

+2

@Brian Вы хотите сказать, что импорт пространства имен в глобальную область в порядке? – AraK

+1

Я скажу, что все в порядке. Не в файле заголовка, но все в порядке. Плохо быть догматичным в отношении этих вещей, и в большинстве случаев это не страшно. Например, если я собираюсь использовать библиотеку графов в исходном файле, все в порядке сказать «using namespace MyGraphLibrary;». Мир не взорвется, ваш код будет в порядке. Это не загрязнение, если вы будете осторожны в этом. – rlbond

8

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

Основная проблема - конфликты имен, в том случае, если у вас есть переменная 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 в верхней части каждого файла - это не путь. В большинстве случаев используйте его для общепринятых классов.

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

+0

+1: интересная мысль об использовании 'std :: swap', с которой я лично не согласен. Однако после прочтения публикации USENET с 2000 года (http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/b396fedad7dcdc81) по этому вопросу меня больше интересует. Лично я предпочитаю _use 'std :: swap' и специализируюсь на этом лагере. –

3

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

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 

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

+3

Ни один из них не является более или менее читаемым, потому что вы не используете никаких пробелов вокруг своих символов. Фрагменты кода на SO все еще могут выглядеть __nice__. –

1

Я хотел бы отметить, что 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

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

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

+0

+1 за последнее предложение! :) – missingfaktor

0

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

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

особенно если у вас есть фирменный стиль СНИМИТЕ предельных линий до 80 символов и добавить еще несколько отступов. Что-то вроде этого скрывает логику кода за всеми формулировками. В этот момент вы начинаете ценить использование и/или локальных псевдонимов пространства имен в интересах удобочитаемости.

Смежные вопросы