Используя std:: <type> v.s. используя пространство имен std

Два способа использования объявления использования:

using std::string;
using std::vector;

или

using namespace std;

какой путь лучше?

========= Удовлетворительный ответ Ниже =============

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

Часто нам нравится использовать каждое имя из пространства имен без квалификация. Это может быть достигнуто путем предоставления декларации использования для каждого имени из пространства имен, но это утомительно и требует дополнительная работа каждый раз, когда новое имя добавляется или удаляется из Пространство имен. В качестве альтернативы мы можем использовать директиву, чтобы каждое имя из пространства имен доступно в нашей области без квалификация. [...] [...] Использование директивы using для создания имен из часто используемая и хорошо известная библиотека, доступная без квалификация - популярный способ упрощения кода. Это техника, используемая для доступа к средствам стандартной библиотеки во всем этом книга. [...] Внутри функции можно использовать директиву с использованием но следует уделить внимание глобальным используя-директивы, потому что чрезмерное использование может привести к тому, что пространства имен были введены во избежание. [...] Следовательно, мы должны будьте осторожны с использованием директив в глобальном масштабе. В частности, не размещайте директиву-указатель в глобальной области видимости в файле заголовка за исключением особых обстоятельств (например, для содействия переходу) потому что вы никогда не знаете, где заголовок может быть включен.

Кредит Джонатана Вакли за цитату.

Ответы

Ответ 1

Это зависит.

Если вы хотите вставить одно имя в другую область видимости, лучше использовать объявление-декларацию, например

namespace foolib
{
  // allow vector to be used unqualified within foo,
  // or used as foo::vector
  using std::vector;

  vector<int> vec();

  template<typename T> struct Bar { T t; };

  template<typename T>
  void swap(Bar<T>& lhs, Bar<T>& rhs)
  {
    using std::swap;
    // find swap by ADL, otherwise use std::swap
    swap(lhs.t, rhs.t);
  }
}

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

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

#include <vector>
#include <iostream>
#include "foolib.h"
using namespace foo;  // only AFTER all headers

Bar<int> b;

Причиной использования директивы using является то, что пространство имен содержит только небольшое количество имен, которые сохраняются намеренно разделенными и предназначены для использования с помощью директивы-указателя:

#include <string>
// make user-defined literals usable without qualification,
// without bringing in everything else in namespace std.
using namespace std::string_literals;
auto s = "Hello, world!"s;

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

Что касается первого использования using namespace, то создатель С++, Bjarne Stroustrup, имеет это сказать в §14.2.3 языка программирования С++, 4-е изд. (выделено мной):

Часто нам нравится использовать любое имя из пространства имен без квалификации. Это может быть достигнуто путем предоставления using -declaration для каждого имени из пространства имен, но это утомительно и требует дополнительной работы каждый раз, когда новое имя добавляется или удаляется из пространства имен. В качестве альтернативы мы можем использовать директиву using, чтобы запросить, чтобы каждое имя из пространства имен было доступно в нашей области без квалификации. [...]
[...] Использование using -directive для создания имен из часто используемой и хорошо известной библиотеки, доступной без квалификации, является популярным методом упрощения кода. Это метод, используемый для доступа к средствам стандартной библиотеки в этой книге. [...]
Внутри функции директиву using можно безопасно использовать в качестве нотации, но следует соблюдать глобальные директивы using, поскольку чрезмерное использование может привести к точному конфликту имен, которые были введены для пространств имен. [...]
Следовательно, мы должны быть осторожны с using -directives в глобальной области. В частности, не размещайте директиву using в глобальной области видимости в файле заголовка, за исключением особых условий (например, для перехода на переход), потому что вы никогда не знаете, где заголовок может быть #include d.

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

Ответ 2

using std::string; и using std::vector;.

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

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