Что требует от меня объявить "использование пространства имен std;"? - PullRequest
16 голосов
/ 07 февраля 2010

Этот вопрос может быть повторен, но я не могу найти хороший ответ. Коротко и просто, что требует от меня объявить

using namespace std;

в программах на C ++?

Ответы [ 12 ]

44 голосов
/ 07 февраля 2010

Поскольку принят стандарт C ++, практически вся стандартная библиотека находится внутри пространства имен std. Поэтому, если вы не хотите квалифицировать все вызовы стандартной библиотеки с помощью std::, вам необходимо добавить директиву using.

Тем не менее,

using namespace std;

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

using std::string;
22 голосов
/ 07 февраля 2010

Ничего не значит, это сокращение, чтобы избежать префикса в этом пространстве имен с помощью std ::

7 голосов
/ 08 февраля 2010

Технически вам может потребоваться использовать , используя (для целых пространств имен или отдельных имен), чтобы иметь возможность использовать Argument Dependent Lookup.

Рассмотрим две следующие функции, которые используют swap().

#include <iostream>
#include <algorithm>

namespace zzz
{
    struct X {};


void swap(zzz::X&, zzz::X&) 
{
    std::cout << "Swapping X\n";
}
}

template <class T>
void dumb_swap(T& a, T& b)
{
    std::cout << "dumb_swap\n";
    std::swap(a, b);
}

template <class T>
void smart_swap(T& a, T& b)
{
    std::cout << "smart_swap\n";
    using std::swap;
    swap(a, b);
}

int main()
{
    zzz::X a, b;
    dumb_swap(a, b);
    smart_swap(a, b);

    int i, j;
    dumb_swap(i, j);
    smart_swap(i, j);
}

dumb_swap всегда вызывает std::swap - хотя мы бы предпочли использовать zzz::swap для zzz::X объектов.

smart_swap делает std::swap видимым как запасной вариант (например, при вызове с целыми числами), но, поскольку он не полностью определяет имя, zzz::swap будет использоваться через ADL для zzz::X.


Субъективно, что заставляет меня использовать using namespace std; - это написание кода, который использует все виды стандартных функциональных объектов и т. Д.

//copy numbers larger than 1 from stdin to stdout
remove_copy_if(
    std::istream_iterator<int>(std::cin), std::istream_iterator<int>(),
    std::ostream_iterator<int>(std::cout, "\n"),
    std::bind2nd(std::less_equal<int>(), 0)
);

IMO, в таком коде std:: просто создает помехи в линии.

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

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

5 голосов
/ 07 февраля 2010

Вы точно не должны говорить:

using namespace std;

в ваших заголовках C ++, потому что это превосходит весь смысл использования пространств имен (это будет означать "загрязнение пространства имен") Вот некоторые полезные ресурсы по этой теме:

1) поток переполнения стека на Стандартное соглашение для использования «std»

2) статья Херба Саттера о Миграция в пространства имен

3) FAQ 27.5 из C ++ Faq lite Маршалла Клайна.

5 голосов
/ 07 февраля 2010

Возможность обращаться к членам в пространстве имен std без необходимости явно ссылаться на std::member.Например:

#include <iostream>
using namespace std;

...
cout << "Hi" << endl;

против

#include <iostream>

...
std::cout << "Hi" << std::endl;
3 голосов
/ 07 февраля 2010

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

Директива using фактически никогда не требуется в C ++, так как любой из элементов, найденных в пространстве имен, может быть доступен напрямую, если вместо них использовать префикс std::. Так, например:

using namespace std;
string myString;

эквивалентно:

std::string myString;

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

using std::string;
string myString;

Это позволяет вам отображать только те элементы в пространстве имен std, которые вам особенно нужны, без риска непреднамеренного раскрытия того, что вы не намеревались.

3 голосов
/ 07 февраля 2010

Прежде всего, это не требуется в C - C не имеет пространств имен. В C ++ - все, что находится в пространстве имен std, которое включает большую часть стандартной библиотеки. Если вы этого не сделаете, вы должны получить доступ к членам пространства имен в явном виде, например:

std::cout << "I am accessing stdout" << std::endl;
1 голос
/ 07 февраля 2010

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

Файл common1.h:

namespace intutils
{
    int addNumbers(int a, int b)
    {
        return a + b;
    }
}

Файл использования:

#include "common1.h"    
int main()
{
    int five = 0;
    five = addNumbers(2, 3); // Will fail to compile since the function is in a different namespace.
    five = intutils::addNumbers(2, 3); // Will compile since you have made explicit which namespace the function is contained within.

    using namespace intutils;
    five = addNumbers(2, 3); // Will compile because the previous line tells the compiler that if in doubt it should check the "intutils" namespace.
}

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

0 голосов
/ 08 февраля 2010

Ничего требует от вас - если вы не являетесь разработчиком стандартной библиотеки C ++ и не хотите избежать дублирования кода при объявлении заголовочных файлов как в «новом», так и в «старом» стиле:

// cstdio
namespace std
{
  // ...
  int printf(const char* ...);
  // ...
}

.

// stdio.h
#include <cstdio>
using namespace std;

Ну, конечно, пример несколько надуманный (вы могли бы с таким же успехом использовать обычный <stdio.h> и поместить все это в std в <cstdio>), но Bjarne Stroustrup показывает этот пример в своем Язык программирования C ++ .

0 голосов
/ 07 февраля 2010

Вы никогда не должны объявлять, используя пространство имен std; его использование - плохая практика, и вы должны использовать std ::, если вы не хотите вводить std :: всегда, вы можете сделать что-то подобное в некоторых случаях:

using std::cout;

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

Rgds Лэйн

...