[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
]