10 Declarations [dcl.dcl]

10.3 Namespaces [basic.namespace]

10.3.4 Using directive [namespace.udir]

using-directive:
	attribute-specifier-seqopt using  namespace nested-name-specifieropt namespace-name ;

A using-directiveне должен появляться в области класса, но может появляться в области пространства имен или в области блока. [ Note: При поиске a namespace-nameв a using-directiveучитываются только имена пространств имен, см [basic.lookup.udir]. ] Необязательный элемент принадлежит к .end noteattribute-specifier-sequsing-directive

A using-directiveуказывает, что имена в назначенном пространстве имен могут использоваться в области, в которой using-directiveпоявляется после using-directive. При unqualified name lookupэтом имена выглядят так, как если бы они были объявлены в ближайшем охватывающем пространстве имен, которое содержит как пространство имен, так using-directiveи назначенное пространство имен. [ Note: В этом контексте «содержит» означает «содержит прямо или косвенно». ]end note

A using-directiveне добавляет элементы в декларативную область, в которой находится. [Example:

namespace A {
  int i;
  namespace B {
    namespace C {
      int i;
    }
    using namespace A::B::C;
    void f1() {
      i = 5;        // OK, C​::​i visible in B and hides A​::​i
    }
  }
  namespace D {
    using namespace B;
    using namespace C;
    void f2() {
      i = 5;        // ambiguous, B​::​C​::​i or A​::​i?
    }
  }
  void f3() {
    i = 5;          // uses A​::​i
  }
}
void f4() {
  i = 5;            // ill-formed; neither i is visible
}

end example]

Для получения unqualified lookup, то using-directiveтранзитивность: если сфера содержит , using-directiveчто выдвигает второе пространство имен , которое само по себе содержит using-directives, эффект , как если бы using-directives из второго пространства имен также появилась в первом. [ Note: Для квалифицированного поиска см [namespace.qual]. ] [ end noteExample:

namespace M {
  int i;
}

namespace N {
  int i;
  using namespace M;
}

void f() {
  using namespace N;
  i = 7;            // error: both M​::​i and N​::​i are visible
}

Другой пример:

namespace A {
  int i;
}
namespace B {
  int i;
  int j;
  namespace C {
    namespace D {
      using namespace A;
      int j;
      int k;
      int a = i;    // B​::​i hides A​::​i
    }
    using namespace D;
    int k = 89;     // no problem yet
    int l = k;      // ambiguous: C​::​k or D​::​k
    int m = i;      // B​::​i hides A​::​i
    int n = j;      // D​::​j hides B​::​j
  }
}

end example]

Если пространство имен находится extended после a using-directiveдля этого пространства имен, дополнительные члены расширенного пространства имен и члены пространств имен, назначенные using-directives в расширении, namespace-definitionмогут использоваться после расширения namespace-definition.

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

namespace A {
  class X { };
  extern "C"   int g();
  extern "C++" int h();
}
namespace B {
  void X(int);
  extern "C"   int g();
  extern "C++" int h(int);
}
using namespace A;
using namespace B;

void f() {
  X(1);             // error: name X found in two namespaces
  g();              // OK: name g refers to the same entity
  h();              // OK: overload resolution selects A​::​h
}

end note]

Во время разрешения перегрузки все функции из транзитивного поиска рассматриваются для сопоставления аргументов. Набор объявлений, найденных при переходном поиске, неупорядочен. [ Note: В частности, порядок, в котором рассматривались пространства имен, и отношения между пространствами имен, подразумеваемые using-directives элементом, не приводят к тому, что предпочтение отдается никаким объявлениям, найденным в результате поиска. ] Двусмысленность существует, если наилучшее соответствие находит две функции с одинаковой сигнатурой, даже если одна находится в пространстве имен, доступном через пространство имен другой. [end noteusing-directives 99Example:

namespace D {
  int d1;
  void f(char);
}
using namespace D;

int d1;             // OK: no conflict with D​::​d1

namespace E {
  int e;
  void f(int);
}

namespace D {       // namespace extension
  int d2;
  using namespace E;
  void f(int);
}

void f() {
  d1++;             // error: ambiguous ​::​d1 or D​::​d1?
  ::d1++;           // OK
  D::d1++;          // OK
  d2++;             // OK: D​::​d2
  e++;              // OK: E​::​e
  f(1);             // error: ambiguous: D​::​f(int) or E​::​f(int)?
  f('a');           // OK: D​::​f(char)
}

end example]

Во время поиска имени в иерархии классов некоторые двусмысленности могут быть разрешены путем рассмотрения того, скрывает ли один член другого на некоторых путях ([class.member.lookup]). При рассмотрении набора имен, найденных в результате следования, такого разрешения неоднозначности нет using-directives.