[namespace.qual] (original) (raw)

6 Basics [basic]

6.5 Name lookup [basic.lookup]

6.5.3 Qualified name lookup [basic.lookup.qual]

6.5.3.2 Namespace members [namespace.qual]

For a namespace X and name m, the namespace-qualified lookup set is defined as follows: Let be the set of all declarations of m in X and the inline namespace set ofX ([namespace.def]) whose potential scope ([basic.scope.namespace]) would include the namespace in which m is declared at the location of the nested-name-specifier.

If is not empty, is ; otherwise, is the union of for all namespaces nominated by using-directives inX and its inline namespace set.

Given X​::​m (where X is a user-declared namespace), or given ​::​m (where X is the global namespace), if is the empty set, the program is ill-formed.

Otherwise, if has exactly one member, or if the context of the reference is a using-declaration, is the required set of declarations of m.

Otherwise if the use ofm is not one that allows a unique declaration to be chosen from, the program is ill-formed.

[ Example

:

int x; namespace Y { void f(float); void h(int); }

namespace Z { void h(double); }

namespace A { using namespace Y; void f(int); void g(int); int i; }

namespace B { using namespace Z; void f(char); int i; }

namespace AB { using namespace A; using namespace B; void g(); }

void h() { AB::g();

AB::f(1);

AB::f('c');

AB::x++;

AB::i++;

AB::h(16.8);

}

end example

]

[ Note

:

The same declaration found more than once is not an ambiguity (because it is still a unique declaration).

[ Example

:

namespace A { int a; }

namespace B { using namespace A; }

namespace C { using namespace A; }

namespace BC { using namespace B; using namespace C; }

void f() { BC::a++;
}

namespace D { using A::a; }

namespace BD { using namespace B; using namespace D; }

void g() { BD::a++;
}

end example

]

end note

]

[ Example

:

Because each referenced namespace is searched at most once, the following is well-defined:

namespace B { int b; }

namespace A { using namespace B; int a; }

namespace B { using namespace A; }

void f() { A::a++;
B::a++;
A::b++;
B::b++;
}

end example

]

During the lookup of a qualified namespace member name, if the lookup finds more than one declaration of the member, and if one declaration introduces a class name or enumeration name and the other declarations introduce either the same variable, the same enumerator, or a set of functions, the non-type name hides the class or enumeration name if and only if the declarations are from the same namespace; otherwise (the declarations are from different namespaces), the program is ill-formed.

[ Example

:

namespace A { struct x { }; int x; int y; }

namespace B { struct y { }; }

namespace C { using namespace A; using namespace B; int i = C::x;
int j = C::y;
}

end example

]

[ Example

:

namespace A { namespace B { void f1(int); } using namespace B; } void A::f1(int){ }

end example

]

[ Example

:

namespace A { namespace B { void f1(int); } }

namespace C { namespace D { void f1(int); } }

using namespace A; using namespace C::D; void B::f1(int){ }

end example

]