6 Basics [basic]

6.5 Name lookup [basic.lookup]

6.5.1 General [basic.lookup.general]

The name lookup rules apply uniformly to all names (including typedef-names ([dcl.typedef]), namespace-names ([basic.namespace]), and class-names ([class.name])) wherever the grammar allows such names in the context discussed by a particular rule.
Name lookup associates the use of a name with a set of declarations ([basic.def]) of that name.
Unless otherwise specified, the program is ill-formed if no declarations are found.
If the declarations found by name lookup all denote functions or function templates, the declarations are said to form an overload set.
Otherwise, if the declarations found by name lookup do not all denote the same entity, they are ambiguous and the program is ill-formed.
Overload resolution ([over.match], [over.over]) takes place after name lookup has succeeded.
The access rules ([class.access]) are considered only once name lookup and function overload resolution (if applicable) have succeeded.
Only after name lookup, function overload resolution (if applicable) and access checking have succeeded are the semantic properties introduced by the declarations used in further processing.
A program point P is said to follow any declaration in the same translation unit whose locus ([basic.scope.pdecl]) is before P.
[Note 1:
The declaration might appear in a scope that does not contain P.
— end note]
A declaration X precedes a program point P in a translation unit L if P follows X, X inhabits a class scope and is reachable from P, or else X appears in a translation unit D and
[Note 3:
A module-import-declaration imports both the named translation unit(s) and any modules named by exported module-import-declarations within them, recursively.
[Example 1:

Translation unit #1:export module Q; export int sq(int i) { return i*i; }

Translation unit #2:export module R; export import Q;

Translation unit #3:import R; int main() { return sq(9); } // OK: sq from module Q — end example]

— end note]
A single search in a scope S for a name N from a program point P finds all declarations that precede P to which any name that is the same as N ([basic.pre]) is bound in S.
If any such declaration is a using-declarator whose terminal name ([expr.prim.id.unqual]) is not dependent ([temp.dep.type]), it is replaced by the declarations named by the using-declarator ([namespace.udecl]).
In certain contexts, only certain kinds of declarations are included.
After any such restriction, any declarations of classes or enumerations are discarded if any other declarations are found.
[Note 4:
A type (but not a typedef-name or template) is therefore hidden by any other entity in its scope.
— end note]
However, if a lookup is type-only, only declarations of types and templates whose specializations are types are considered; furthermore, if declarations of a typedef-name and of the type to which it refers are found, the declaration of the typedef-name is discarded instead of the type declaration.