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

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

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

1968
задан akbiggs 21 сент. '09 в 6:08
источник поделиться

35 ответов

  • 1
  • 2

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

using namespace foo;
using namespace bar;

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

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

1666
ответ дан Greg Hewgill 21 сент. '09 в 6:13
источник поделиться

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

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

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

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


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

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


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

1103
ответ дан sbi 21 сент. '09 в 12:26
источник поделиться

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

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


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

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

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

  • A с использованием объявления:

    using std::cout; // a using-declaration lets you use cout without qualification
    cout << "Values:";
    
  • Обходите это и просто наберите std::

    std::cout << "Values:";
    
299
ответ дан ChrisW 21 сент. '09 в 6:22
источник поделиться

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

using namespace std;
using namespace boost;

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

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

186
ответ дан David Thornley 28 окт. '10 в 20:37
источник поделиться

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

Резюме

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

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

Обсуждение

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

148
ответ дан mattnewport 03 нояб. '14 в 23:00
источник поделиться

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

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...) потому что он короче и имеет возможность работать с определенными пользователем типами с плавающей запятой (через зависимый от аргумента поиск).

97
ответ дан robson3.14 21 сент. '09 в 18:47
источник поделиться

Не используйте его глобально

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

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

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

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

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

В С++ 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&) и попытаться наилучшим образом заменить их.

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

74
ответ дан towi 18 янв. '13 в 12:34
источник поделиться

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

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

68
ответ дан sth 21 сент. '09 в 6:23
источник поделиться

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

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 (using namespace Her_lib).

30
ответ дан Oleksiy 29 авг. '13 в 12:44
источник поделиться

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

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

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

Итак, все в порядке:

  • Использование-директив на уровне функций и использование-деклараций внутри реализации функций
  • Использование-объявления уровня исходного файла в исходных файлах
  • (Иногда) с использованием-директив на уровне исходного файла
30
ответ дан Alexander Poluektov 29 марта '11 в 11:10
источник поделиться

Еще одна причина - сюрприз.

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

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

27
ответ дан Martin Beckett 21 сент. '09 в 6:13
источник поделиться

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

19
ответ дан Yelonek 21 сент. '09 в 12:34
источник поделиться

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

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

15
ответ дан Preet Sangha 21 сент. '09 в 6:14
источник поделиться

Приятно видеть код и знать, что он делает. Если я вижу std::cout, я знаю, что поток cout библиотеки std. Если я увижу cout, то я не знаю. Это может быть поток cout библиотеки std. Или может быть int cout = 0; десять строк выше в одной и той же функции. Или переменная static с именем cout в этом файле. Это может быть что угодно.

Теперь возьмите миллионную строку кода линии, которая не особенно велика, и вы ищете ошибку, а это означает, что вы знаете, что есть одна строка в этом миллионе строк, которая не делает то, что предполагается делать. cout << 1; может читать a static int с именем cout, сдвигать его влево на один бит и отбрасывать результат. Глядя на ошибку, я должен проверить это. Вы видите, как я действительно предпочитаю видеть std::cout?

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

14
ответ дан gnasher729 13 марта '14 в 20:22
источник поделиться
  • вам нужно уметь читать код, написанный людьми, которые имеют разные мнения о стиле и лучшей практике, чем вы.

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

12
ответ дан Dustin Getz 21 сент. '09 в 7:04
источник поделиться

Рассмотрим

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


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

class stringstream {  // uh oh
};

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

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

11
ответ дан Ron Warholic 21 сент. '09 в 6:19
источник поделиться

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

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

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

11
ответ дан user2645752 09 нояб. '13 в 18:09
источник поделиться

Конкретный пример для разъяснения проблемы. Представьте, что у вас есть ситуация, когда у вас есть 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 (из-за количества вещей в этом пространстве имен), чем другие пространства имен.

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

9
ответ дан Kevin 02 сент. '16 в 23:06
источник поделиться

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

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
    / / ...
}

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

Источник: обзор языка программирования С++ by Bjarne Stroustrup

8
ответ дан Rohan Singh 05 апр. '15 в 15:56
источник поделиться

Я согласен с остальными здесь, но хотел бы затронуть проблемы, связанные с удобочитаемостью - вы можете избежать всего этого, просто используя 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;
}
7
ответ дан Carl 12 февр. '15 в 3:40
источник поделиться

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

#include <iostream>

using namespace std;

int count = 1;
int main() {
    cout<<count<<endl;
}
6
ответ дан Nithin 31 дек. '15 в 11:00
источник поделиться

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

4
ответ дан Dr. Watson 21 сент. '09 в 6:34
источник поделиться

"Почему" using namespace std; "считается плохой практикой в ​​С++?"

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

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

4
ответ дан Solkar 13 мая '13 в 18:18
источник поделиться

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

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

3
ответ дан Engine Dev 21 авг. '16 в 1:55
источник поделиться

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

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

ПРИМЕЧАНИЕ. Не сосредотачивайтесь слишком много на проблемах эффективности, пока вы не узнаете немного о том, как работают компиляторы. С небольшим опытом кодирования вам не нужно много узнавать о них, прежде чем вы поймете, насколько они могут обобщить хороший код во что-то простое. Каждый бит такой же простой, как если бы вы написали все это в C. Хороший код настолько сложный, насколько он должен быть.

3
ответ дан Noneyo Getit 27 июня '13 в 23:33
источник поделиться

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

3
ответ дан August Karlstrom 11 апр. '13 в 17:22
источник поделиться

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

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

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

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

Кроме того, вы можете иметь псевдонимы пространства имен. Вот пример того, где это полезно, о котором, возможно, не упоминалось (я не читал все ответы, и мне нужно некоторое время сбежать). Я использую стандарт С++ 11 и, в частности, с libstdС++. Хорошо проверьте это. Он не имеет полной поддержки std:: regex. Конечно, он компилируется, но он выдает исключение по тому, что это ошибка на конце программиста. Но это недостаток в реализации. Итак, вот как я это решил. Установите boost regex, ссылку в boost regex. Затем я делаю следующее, чтобы, когда libstdС++ полностью реализовал его, мне нужно только удалить этот блок, а код останется тем же:

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;  
}

Я не буду спорить о том, что это плохая идея или нет. Тем не менее я утверждаю, что он сохраняет чистоту для проекта MY и в то же время делает его конкретным: True Я должен использовать boost, но я использую его, как libstdС++, в конце концов его получит. Да, начинать свой собственный проект и начинать со стандартного (...) в самом начале очень долгий путь, помогая поддержанию, развитию и всему, что связано с проектом!

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

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

3
ответ дан user4138451 13 окт. '14 в 20:30
источник поделиться

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

3
ответ дан MathGladiator 21 сент. '09 в 6:15
источник поделиться

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

2
ответ дан adn.911 30 нояб. '17 в 19:24
источник поделиться

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

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

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

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

И посмотрите это мнение:

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

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

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

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

...

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

...

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

2
ответ дан CryogenicNeo 23 апр. '18 в 20:15
источник поделиться
  • 1
  • 2

Другие вопросы по меткам