Почему "использование пространства имен std" считается плохой практикой?

мне говорили другие, что писать using namespace std в коде неправильно, и что я должен использовать std::cout и std::cin напрямую, а не.

почему using namespace std считается плохой практикой? Является ли он неэффективным или он рискует объявить неоднозначные переменные (переменные, которые имеют то же имя, что и функция в std пространство имен)? Влияет ли это на производительность?

30 ответов


это не связано с производительностью вообще. Но подумайте вот о чем: вы используете две библиотеки под названием Foo и Bar:

using namespace foo;
using namespace bar;

все работает нормально, вы можете позвонить Blah() от Foo и Quux() из бара без проблем. Но однажды вы обновитесь до новой версии Foo 2.0, которая теперь предлагает функцию под названием Quux(). Теперь у вас есть конфликт: как Foo 2.0, так и Bar import Quux() в глобальном пространстве имен. Это потребует некоторых усилий, чтобы исправить, особенно если параметры функции совпадают.

если бы вы использовали foo::Blah() и bar::Quux(), затем введение foo::Quux() было бы событием.


Я согласен со всем Грег писал, но я хотел бы добавить: это может быть даже хуже, чем сказал Грег!

библиотека Foo 2.0 может ввести функцию Quux(), Это однозначно лучше подходит для некоторых ваших звонков Quux() чем bar::Quux() ваш код вызывается годами. Тогда ваш код все еще компилируется, а он молча вызывает неправильную функцию и бог-знает-что. Это самое плохое, что может быть.

имейте в виду, что std пространство имен имеет множество идентификаторов, многие из которых являются очень общие (думаю list, sort, string, iterator, etc.) которые, скорее всего, появятся и в другом коде.

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


вот еще одна точка данных: много, много лет назад я также считал раздражающим, что нужно префикс все из стандартной библиотеки с std::. Затем я работал в проекте, где с самого начала было решено, что оба using директивы и объявления запрещены, за исключением области видимости функций. Знаешь что? Большинству из нас потребовалось всего несколько недель, чтобы привыкнуть к написанию префикса, а еще через несколько недель большинство из нас даже согласились с тем, что это действительно код более читабельным. Для этого есть причина:нравится ли вам короче или длиннее проза субъективна, но префиксы объективно добавляют ясности в код. не только компилятор, но и Вам также легче увидеть, на какой идентификатор ссылаются.

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


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


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

тем не менее, вы можете свободно поместить оператор using в свой (частный) *.cpp-файлы.


остерегайтесь, что некоторые люди не согласны с моим высказыванием "Не стесняйтесь", как это-потому что, хотя оператор using в файле cpp is лучше чем в заголовке (потому что это не влияет на людей, которые включают ваш файл заголовка), они думают, что это все еще не хороший (потому что в зависимости от кода это может затруднить реализацию класса). этот FAQ тема говорит,

директива using-существует для устаревшего кода C++ и для облегчения перехода в пространства имен, но вы, вероятно, не должны использовать ее на регулярной основе, по крайней мере, не в новом Код C++.

он предлагает две альтернативы:

  • С помощью декларации:

    using std::cout; // a using-declaration lets you use cout without qualification
    cout << "Values:";
    
  • преодолейте это и просто введите std::

    std::cout << "Values:";
    

недавно я столкнулся с жалобой на Visual Studio 2010. Оказалось, что почти все исходные файлы имели эти две строки:

using namespace std;
using namespace boost;

большое Boost функции переходят в стандарт C++0x, а Visual Studio 2010 имеет множество функций C++0x, поэтому внезапно эти программы не компилировались.

поэтому, во избежание using namespace X; - это форма будущей проверки, способ убедиться в изменении библиотек и / или заголовка используемые файлы не нарушат программу.


краткая версия: не используйте глобальные объявления или директивы в заголовочных файлах. Не стесняйтесь использовать их в файлах реализации. Вот что Херб Саттер и Андрей Александреску должны сказать об этом вопросе в Стандарты Кодирования C++ (выделено жирным шрифтом):

резюме

использование пространства имен для вашего удобства, а не для вас, чтобы наносить другим: никогда не пишите объявление using или директиву using перед #include директива.

следствие: в заголовочных файлах не записывайте уровень пространства имен с помощью директив или деклараций; вместо этого явно пространство имен-квалифицируйте все имена. (Второе правило следует из первого, потому что заголовки никогда не могут знать, какие другие заголовки #includes могут появиться после них.)

Обсуждение

короче говоря: вы можете и должны использовать пространство имен, используя объявления и директивы в своих файлах реализации после # include директив и чувствовать себя хорошо. несмотря на неоднократные утверждения об обратном, пространство имен с использованием деклараций и директив не является злом, и они не побеждают цель пространств имен. Скорее, это то, что делает пространства имен полезными.


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

template <typename FloatType> inline
FloatType compute_something(FloatType x)
{
    using namespace std; //no problem since scope is limited
    return exp(x) * (sin(x) - cos(x * 2) + sin(x * 3) - cos(x * 4));
}

Это лучше, чем явная квалификация (std::sin, std::cos...) поскольку он короче и имеет возможность работать с определенными пользователем типами с плавающей запятой (через поиск, зависящий от аргумента).


не используйте его во всем мире

считается "плохим" только тогда, когда используется во всем мире. Потому что:

  • вы загромождает пространство имен программировании на.
  • читателям будет трудно увидеть, откуда берется конкретный идентификатор, когда вы используете много using namespace xyz.
  • что верно для другое читатели вашего исходного кода еще более верны для самого частого читателя: себя. Вернись! год или два и посмотрите...
  • если вы только говорите о using namespace std вы можете не знать обо всех вещах, которые вы хватаете-и когда вы добавляете другой #include или перейти к новой редакции c++, вы можете получить конфликты имен, о которых вы не знали.

вы можете использовать его локально

идите вперед и используйте его локально (почти) свободно. Это, конечно, мешает вам повторить std:: -- и повторение тоже плохо.

идиома для его использования локально

в C++03 была идиома-шаблонный код - для реализации swap функции для ваших классов. Было предложено использовать локальный using namespace std -- или по крайней мере using std::swap:

class Thing {
    int    value_;
    Child  child_;
public:
    // ...
    friend void swap(Thing &a, Thing &b);
};
void swap(Thing &a, Thing &b) {
    using namespace std;      // make `std::swap` available
    // swap all members
    swap(a.value_, b.value_); // `std::stwap(int, int)`
    swap(a.child_, b.child_); // `swap(Child&,Child&)` or `std::swap(...)`
}

это волшебство:

  • компилятор выберет std::swap на value_, то есть void std::swap(int, int).
  • если у вас перегрузка void swap(Child&, Child&) реализовано компилятор выберет его.
  • если у вас не что перегрузки компилятор будет использовать void std::swap(Child&,Child&) и попробуйте его лучший обмен этими.

С C++11 больше нет причин использовать этот шаблон. Реализация std::swap был изменен, чтобы найти потенциальную перегрузку и выбрать ее.


если вы импортируете правильные файлы заголовков, у вас внезапно появляются имена, такие как hex, left, plus или count в глобальной области. Это может быть удивительно, если вы не знаете, что std:: содержит эти имена. Если вы также попытаетесь использовать эти имена локально, это может привести к некоторой путанице.

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


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

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

Что это причины? Иногда программисты явно хотят отключить ADL, в других случаях они хотят устранить двусмысленность.

Итак, следующие в порядке:

  1. Function-level using-директивы и using-объявления внутри реализаций функций
  2. исходный файл-уровень использования-объявления внутри исходных файлов
  3. (иногда) уровень исходного файла с использованием-директив

Я согласен, что он не должен использоваться глобально, но это не так плохо, чтобы использовать локально, как в namespace. Вот пример из " Язык Программирования C++" :

namespace My_lib {

    using namespace His_lib; // everything from His_lib
    using namespace Her_lib; // everything from Her_lib

    using His_lib::String; // resolve potential clash in favor of His_lib
    using Her_lib::Vector; // resolve potential clash in favor of Her_lib

}

в этом примере мы решили потенциальные столкновения имен и двусмысленности, возникающие из их состава.

имена, явно объявленные там (включая имена, объявленные с помощью-объявлений, таких как His_lib::String) приоритет над именами, доступными в другой области использование-директива (using namespace Her_lib).


еще одна причина-удивление.

если я вижу cout << blah, вместо std::cout << blah

Я думаю, что это cout? Это нормально cout? Это что-то особенное?


Я тоже считаю это плохой практикой. Почему? Просто однажды я подумал, что функция пространства имен состоит в том, чтобы разделить вещи, поэтому я не должен портить его, бросая все в один глобальный мешок. Однако, если я часто использую "cout" и "cin", я пишу:using std::cout; using std::cin; в файле cpp (никогда в файле заголовка, поскольку он распространяется с #include). Я думаю, что никто в здравом уме никогда не назовет ручей cout или cin. ;)


приятно видеть код и знать, что он делает. Если я увижу std::cout Я знаю, что это cout поток std библиотека. Если я увижу


Это все об управлении сложностью. Использование пространства имен будет тянуть вещи, которые вы не хотите, и, таким образом, возможно, затруднит отладку (я говорю, возможно). Использование std:: повсюду сложнее читать (больше текста и все такое).

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


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

  2. Если вы используете только cout, никто не запутывается. Но когда у вас много пространств имен, летающих вокруг, и вы видите этот класс, и вы не совсем уверены, что он делает, наличие пространства имен явно действует как комментарий. Вы можете увидеть, на первый взгляд, 'О, это операция файловой системы" или " это делает чепуха.


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

поэтому просто рассмотрите их функции как зарезервированные имена, такие как" int "или" class", и все.

люди должны перестать быть такими анальными об этом. Твой учитель был прав с самого начала. Просто используйте одно пространство имен; в этом весь смысл использование пространств имен в первую очередь. Вы не должны использовать более одного одновременно. Если только это не ваше собственное. Поэтому, опять же, переопределения не произойдет.


рассмотрим

// myHeader.h
#include <sstream>
using namespace std;


// someoneElses.cpp/h
#include "myHeader.h"

class stringstream {  // uh oh
};

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

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


пространство имен-это именованная область. Пространства имен используются для группировки связанных объявлений и сохранения отдельных пункты раздельные. Например, две отдельно разработанные библиотеки могут использовать одно и то же имя для ссылки на разные элементы, но пользователь все равно может использовать оба:

namespace Mylib{
    template<class T> class Stack{ /* ... */ };
    / / ...
}
namespace Yourlib{
    class Stack{ /* ... */ };
    / / ...
}
void f(int max) {
    Mylib: :Stack<int> s1(max) ; / / use my stack
    Yourlib: :Stack s2(max) ; / / use your stack
    / / ...
}

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

void f(int max) {
    using namespace Mylib; / / make names from Mylib accessible
    Stack<int> s1(max) ; / / use my stack
    Yourlib: :Stack s2(max) ; / / use your stack
    / / ...
}

пространства имен предоставляют мощный инструмент для управления различными библиотеками и различными версиями код. В частности, они предлагают программисту альтернативы того, как явно сделать ссылку на нелокальную имя.

источник : обзор языка программирования C++ Бьярне Страуструп


конкретный пример, чтобы прояснить озабоченность. Представьте, что у вас есть ситуация, когда у вас есть 2 библиотеки, foo и bar, каждая со своим собственным пространством имен:

namespace foo {
    void a(float) { /* does something */ }
}

namespace bar {
    ...
}

теперь предположим, что вы используете foo и bar вместе в своей собственной программе следующим образом:

using namespace foo;
using namespace bar;

void main() {
    a(42);
}

на данный момент все нормально. Когда вы запускаете свою программу, она "что-то делает". Но позже вы обновите панель и скажем, что она изменилась, чтобы быть похожей:

namespace bar {
    void a(float) { /* does something completely different */ }
}

в этот момент Вы получите ошибка компилятора:

using namespace foo;
using namespace bar;

void main() {
    a(42);  // error: call to 'a' is ambiguous, should be foo::a(42)
}

поэтому вам нужно будет сделать некоторое обслуживание, чтобы уточнить, какой " a " вы имели в виду (т. е. foo::a). Это, вероятно, нежелательно, но, к счастью, это довольно легко (просто добавьте foo:: перед всеми звонками в a что компилятор отмечает как неоднозначный).

но представьте себе альтернативный сценарий, где бар изменился вместо этого, чтобы выглядеть так:

namespace bar {
    void a(int) { /* does something completely different */ }
}

в этот момент ваш вызов a(42) вдруг привязывается к bar::a вместо foo::a и вместо того, чтобы делать "что-то", он делает "что-то совершенно другое". Нет предупреждения компилятора или что-то еще. Ваша программа просто молча начинает делать что-то совершенно другое, чем раньше.

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

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


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

#include <iostream>

using namespace std;

int count = 1;
int main() {
    cout<<count<<endl;
}

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

Я обычно использую его в объявлении класса, поскольку методы в классе имеют тенденцию иметь дело с аналогичными типами данных (членами), а typedef-это возможность назначить имя, которое имеет смысл в контексте класса. Это фактически помогает удобочитаемости в определениях метод класса.

//header
class File
{
   typedef std::vector<std::string> Lines;
   Lines ReadLines();
}

и в реализации:

//cpp
Lines File::ReadLines()
{
    Lines lines;
    //get them...
    return lines;
}

против:

//cpp
vector<string> File::ReadLines()
{
    vector<string> lines;
    //get them...
    return lines;
}

или:

//cpp
std::vector<std::string> File::ReadLines()
{
    std::vector<std::string> lines;
    //get them...
    return lines;
}

"Почему" использование пространства имен std; " считается плохой практикой в C++?"

Я поставил его наоборот: почему ввод 5 дополнительных символов считается громоздким некоторыми?

рассмотрим, например, написание части числового программного обеспечения, почему я даже рассматриваю загрязнение моего глобального пространства имен, сокращая общее "std:: vector" до "vector", когда "вектор" является одним из самых важных понятий проблемной области?


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


чтобы ответить на ваш вопрос, я смотрю на это практически так: многие программисты (не все) вызывают пространство имен std. Поэтому следует иметь привычку не использовать вещи, которые сталкиваются или используют те же имена, что и в пространстве имен std. Это очень много, но не так много по сравнению с количеством возможных связных слов и псевдонимов, которые можно придумать строго говоря.

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

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


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

например, если я введу,using namespace std; и using namespace otherlib; и введите просто cout (который находится в обоих), а не std::cout (или 'otherlib::cout'), вы можете использовать неправильный, и получить ошибки, это гораздо более эффективно и эффективно использовать std::cout.


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


Я согласен с другими-он просит столкновения имен, двусмысленности, а затем факт, что он менее явный. Пока я вижу использование using, мое личное предпочтение-ограничить его. Я бы также сильно рассмотрел то, что указали некоторые другие:

если вы хотите найти имя функции, которое может быть довольно распространенным именем, но вы хотите найти его только в std namespace (или наоборот – вы хотите изменить все вызовы, которые не находятся в namespace std, пространства имен X, ...), то как вы предлагаете это сделать? Вы могли бы написать программу для этого, но не лучше ли потратить время на работу над самим проектом, чем писать программу для поддержания вашего проекта?

лично я на самом деле не против std:: префикс. Мне нравится этот вид больше, чем его отсутствие. Я не знаю, потому ли это, что он явный и говорит мне: "это не мой код... Я использую стандартную библиотеку" или если это что-то еще, но я думаю, что это выглядит лучше. Это может быть странно, учитывая, что я только недавно попал в C++ (используется и все еще делает C и другие языки намного дольше, и C-мой любимый язык всех времен, прямо над сборкой).

есть еще одна вещь, хотя она несколько связана с вышеизложенным и с тем, что указывают другие. Хотя это может быть плохой практикой, я иногда резервирую std::name для стандартной версии библиотеки и имени для программной реализации. Да, действительно, это могло бы укусить тебя и сильно укусить, но это ... все сводится к тому, что я начал этот проект с нуля и я единственный программист для этого. Пример: я перегружаю std::string и называть это string. У меня есть полезные дополнения. Я сделал это отчасти из-за моей тенденции C и Unix (+ Linux) к именам в нижнем регистре.

кроме того, вы можете иметь псевдонимы пространства имен. Вот пример того, где это полезно, о чем, возможно, не упоминалось. Я использую стандарт C++11 и, в частности, с libstdc++. Ну, он не имеет полного std::regex поддержка. Конечно, он компилируется, но он выдает исключение по линии того, что это ошибка на конце программиста. Но это недостаточная реализация. Вот как я решил эту проблему. Установите регулярное выражение Boost, свяжите его. Затем я делаю следующее, чтобы, когда libstdc++ полностью реализован, мне нужно только удалить этот блок, и код останется прежним:

namespace std
{
    using boost::regex;
    using boost::regex_error;
    using boost::regex_replace;
    using boost::regex_search;
    using boost::regex_match;
    using boost::smatch;
    namespace regex_constants = boost::regex_constants;  
}

Я не буду спорить о том, что это плохая идея или нет. Однако я буду утверждать, что он держит его в чистоте для моего проекта и в то же время делает его конкретным: правда, я должен использовать Boost, но я использую его, как libstdc++ в конечном итоге будет иметь его. Да, начиная свой собственный проект и начиная со стандарта (...) в самом начале идет очень долгий путь с помощью обслуживания, развития и всего, что связано с проектом!

Edit:
Теперь у меня есть время, чтобы кое-что прояснить. Я не думаю, что это хорошая идея, чтобы использовать имя класса/в STL намеренно и более конкретно вместо. Строка является исключением (игнорируйте первый, выше или второй здесь, каламбур, если нужно) для меня, поскольку мне не понравилась идея "строки". Как бы то ни было, я все еще очень предвзято отношусь к C и предвзято отношусь к c++. Щадящие детали, многое из того, над чем я работаю, больше подходит C (но это было хорошее упражнение и хороший способ сделать себя a). изучите другой язык и b. старайтесь не быть менее предвзятым по отношению к объекту / классам / etc, который, возможно, лучше сформулирован как менее закрытый, менее высокомерным, более терпимым.). Но полезно то, что некоторые уже предложили: я действительно использую list (он довольно общий, не так ли ?), сортировать (то же самое), чтобы назвать два, которые вызвали бы столкновение имен, если бы я должен был сделать using namespace std; и поэтому с этой целью я предпочитаю быть конкретным, контролировать и знать, что если я намерен использовать его в качестве стандарта, то мне придется его указать. Проще говоря: не допускается.

и для усиления регулярных выражений часть std. Я делаю это ради будущего. интеграция и-опять же, я полностью признаю, что это предвзятость - я не думаю, что это так уродливо, как boost::regex:: ... действительно, это другое дело для меня. В C++ есть много вещей, которые мне еще предстоит полностью принять во внешнем виде и методах (другой пример: variadic templates versus var args [хотя я признаю, что variadic templates очень полезны!]). Даже те, которые я принимаю, это было сложно, и у меня все еще есть проблемы с ними.


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

на namespace std содержит стандартные функции и переменные C++. Это пространство имен полезно, когда вы часто используете стандартные функции C++.

как указано в этом страница:

оператор, использующий пространство имен std, обычно считается плохим практиковать. Альтернативой этому заявлению является указание пространство имен, к которому принадлежит идентификатор, с помощью оператора scope(::) каждый раз, когда мы объявляем тип.

и видим такое мнение:

нет проблем с использованием "using namespace std" в исходном файле когда вы интенсивно используете пространство имен и точно знаете, что ничто не столкнется.

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

как упоминается в этом страница:

хотя оператор избавляет нас от ввода std:: whenever мы хотим получить доступ к классу или типу, определенному в пространстве имен std, это импортирует все пространство имен std в текущее пространство имен программы. Давайте возьмем несколько примеров, чтобы понять, почему это может быть, это не так уж и хорошо.--5-->

...

теперь на более поздней стадии разработки мы хотим использовать другую версию суда, что является пользовательский реализован в некоторой библиотеке под названием " foo " (для пример)

...

обратите внимание, как существует двусмысленность, на какую библиотеку указывает cout? Компилятор может обнаружить это и не компилировать программу. В худшем case, программа все еще может компилироваться, но вызывать неправильную функцию, так как мы никогда не указывали, к какому пространству имен принадлежит идентификатор.


с импортных идентификаторы вам нужны внешние инструменты поиска, как grep чтобы узнать, где объявлены идентификаторы. Это затрудняет рассуждения о корректности программы.


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