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 note attribute-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 note Example:
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 note using-directives 99 Example:
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.