Files
cppdraft_translate/cppdraft/namespace/qual.md
2025-10-25 03:02:53 +03:00

4.2 KiB
Raw Blame History

[namespace.qual]

6 Basics [basic]

6.5 Name lookup [basic.lookup]

6.5.5 Qualified name lookup [basic.lookup.qual]

6.5.5.3 Namespace members [namespace.qual]

1

#

Qualified name lookup in a namespace N additionally searches every element of the inline namespace set of N ([namespace.def]).

If nothing is found, the results of the lookup are the results of qualified name lookup in each namespace nominated by a using-directive that precedes the point of the lookup and inhabits N or an element of N's inline namespace set.

[Note 1:

If a using-directive refers to a namespace that has already been considered, it does not affect the result.

— end note]

[Example 1: 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(); // g is declared directly in AB, therefore S is { AB::g() } and AB::g() is chosen AB::f(1); // f is not declared directly in AB so the rules are applied recursively to A and B;// namespace Y is not searched and Y::f(float) is not considered;// S is { A::f(int), B::f(char) } and overload resolution chooses A::f(int) AB::f('c'); // as above but resolution chooses B::f(char) AB::x++; // x is not declared directly in AB, and is not declared in A or B, so the rules// are applied recursively to Y and Z, S is { } so the program is ill-formed AB::i++; // i is not declared directly in AB so the rules are applied recursively to A and B,// S is { A::i, B::i } so the use is ambiguous and the program is ill-formed AB::h(16.8); // h is not declared directly in AB and not declared directly in A or B so the rules// are applied recursively to Y and Z, S is { Y::h(int), Z::h(double) } and// overload resolution chooses Z::h(double)} — end example]

2

#

[Note 2:

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

[Example 2: 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++; // OK, S is { A::a, A::a }}namespace D {using A::a;}namespace BD {using namespace B; using namespace D;}void g(){ BD::a++; // OK, S is { A::a, A::a }} — end example]

— end note]

3

#

[Example 3:

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++; // OK, a declared directly in A, S is { A::a } B::a++; // OK, both A and B searched (once), S is { A::a } A::b++; // OK, both A and B searched (once), S is { B::b } B::b++; // OK, b declared directly in B, S is { B::b }}

— end example]

4

#

[Note 3:

Class and enumeration declarations are not discarded because of other declarations found in other searches.

— end note]

[Example 4: namespace A {struct x { }; int x; int y;}namespace B {struct y { };}namespace C {using namespace A; using namespace B; int i = C::x; // OK, A::x (of type int)int j = C::y; // ambiguous, A::y or B::y} — end example]