#
[Note 1: 
This Clause presents the basic concepts of the C++ language.
It explains the difference between an object and a name and how they relate to the value categories for expressions.
It introduces the concepts of a declaration and a definition and presents C++'s notion of type, scope, linkage, and storage duration.
The mechanisms for starting and terminating a program are discussed.
Finally, this Clause presents the fundamental types of the language and lists the ways of constructing compound types from these.
— end note]
[Note 2: 
This Clause does not cover concepts that affect only a single part of the language.
Such concepts are discussed in the relevant Clauses.
— end note]
Two names are the same if
[Note 3: 
The term declaration is not a synonym for the grammar non-terminal declaration ([dcl.pre]).
— end note]
[Note 4: 
The interpretation of a for-range-declaration produces one or more of the above ([stmt.ranged]).
— end note]
[Note 5: 
Some names denote types or templates.
In general, whenever a name is encountered it is necessary to look it up ([basic.lookup]) to determine whether that name denotes one of these entities before continuing to parse the program that contains it.
— end note]
A variable is introduced by the declaration of
  • a reference other than a non-static data member or
  • an object.
An entity is a variable, structured binding, result binding, function, enumerator, type, type alias, non-static data member, bit-field, template, namespace, namespace alias, template parameter, function parameter, or init-capture.
The underlying entity of an entity is that entity unless otherwise specified.
A name denotes the underlying entity of the entity declared by each declaration that introduces the name.
[Note 6: 
Type aliases and namespace aliases have underlying entities that are distinct from themselves.
— end note]
A local entity is a variable with automatic storage duration ([basic.stc.auto]), a structured binding ([dcl.struct.bind]) whose corresponding variable is such an entity, a result binding ([dcl.contract.res]), or the *this object ([expr.prim.this]).
A name used in more than one translation unit can potentially refer to the same entity in these translation units depending on the linkage of the name specified in each translation unit.

6.2 Declarations and definitions [basic.def]

A declaration ([basic.pre]) may (re)introduce one or more names and/or entities into a translation unit.
If so, the declaration specifies the interpretation and semantic properties of these names.
A declaration of an entity X is a redeclaration of X if another declaration of X is reachable from it ([module.reach]); otherwise, it is a first declaration.
[Note 1: 
A declaration can also have effects including:
— end note]
Each entity declared by a declaration is also defined by that declaration unless:
A declaration is said to be a definition of each entity that it defines.
[Example 1: 
All but one of the following are definitions: int a; / defines a extern const int c = 1; / defines c int f(int x) { return x+a; } / defines f and defines x struct S { int a; int b; }; / defines S, S​::​a, and S​::​b struct X { / defines X int x; / defines non-static data member x static int y; / declares static data member y X(): x(0) { } / defines a constructor of X }; int X::y = 1; / defines X​::​y enum { up, down }; / defines up and down namespace N { int d; } / defines N and N​::​d X anX; / defines anX whereas these are just declarations: extern int a; / declares a extern const int c; / declares c int f(int); / declares f struct S; / declares S typedef int Int; / declares Int namespace N1 = N; / declares N1 extern X anotherX; / declares anotherX using N::d; / declares d
— end example]
[Note 2: 
In some circumstances, C++ implementations implicitly define the default constructor ([class.default.ctor]), copy constructor, move constructor ([class.copy.ctor]), copy assignment operator, move assignment operator ([class.copy.assign]), or destructor member functions.
— end note]
[Example 2: 
Given #include <string> struct C { std::string s; / std​::​string is the standard library class ([string.classes]) }; int main() { C a; C b = a; b = a; } the implementation will implicitly define functions to make the definition of C equivalent to struct C { std::string s; C() : s() { } C(const C& x): s(x.s) { } C(C&& x): s(static_cast<std::string&&>(x.s)) { } / : s(std​::​move(x.s)) { } C& operator=(const C& x) { s = x.s; return *this; } C& operator=(C&& x) { s = static_cast<std::string&&>(x.s); return *this; } / { s = std​::​move(x.s); return *this; } ~C() { } };
— end example]
[Note 3: 
A class name can also be implicitly declared by an elaborated-type-specifier ([dcl.type.elab]).
— end note]
In the definition of an object, the type of that object shall not be an incomplete type ([basic.types.general]), an abstract class type ([class.abstract]), or a (possibly multidimensional) array thereof.
12)12)
Appearing inside the brace-enclosed declaration-seq in a linkage-specification does not affect whether a declaration is a definition.

6.3 One-definition rule [basic.def.odr]

Each of the following is termed a definable item:
No translation unit shall contain more than one definition of any definable item.
An expression or conversion is potentially evaluated unless it is an unevaluated operand ([expr.context]), a subexpression thereof, or a conversion in an initialization or conversion sequence in such a context.
The set of potential results of an expression E is defined as follows:
[Note 1: 
This set is a (possibly-empty) set of id-expressions and splice-expressions, each of which is either E or a subexpression of E.
[Example 1: 
In the following example, the set of potential results of the initializer of n contains the first S​::​x subexpression, but not the second S​::​x subexpression.
The set of potential results of the initializer of o contains the subexpression [:^S​::​x:].
struct S { static const int x = 0; }; const int &f(const int &r); int n = b ? (1, S::x) / S​::​x is not odr-used here : f(S::x); / S​::​x is odr-used here, so a definition is required int o = [:^S::x:]; — end example]
— end note]
A function is named by an expression or conversion as follows:
  • A function is named by an expression or conversion if it is the selected member of an overload set ([basic.lookup], [over.match], [over.over]) in an overload resolution performed as part of forming that expression or conversion, and either it is not a pure virtual function or the expression is an id-expression naming the function with an explicitly qualified name that does not form a pointer to member ([expr.unary.op]).
    [Note 2: 
    This covers taking the address of functions ([conv.func], [expr.unary.op]), calls to named functions ([expr.call]), operator overloading ([over]), user-defined conversions ([class.conv.fct]), allocation functions for new-expressions ([expr.new]), as well as non-default initialization ([dcl.init]).
    A constructor selected to copy or move an object of class type is considered to be named by an expression or conversion even if the call is actually elided by the implementation ([class.copy.elision]).
    — end note]
  • A deallocation function for a class is named by a new-expression if it is the single matching deallocation function for the allocation function selected by overload resolution, as specified in [expr.new].
  • A deallocation function for a class is named by a delete-expression if it is the selected usual deallocation function as specified in [expr.delete] and [class.free].
A variable is named by an expression if the expression is an id-expression or splice-expression ([expr.prim.splice]) that designates it.
A variable x that is named by a potentially-evaluated expression N that appears at a point P is odr-used by N unless
  • x is a reference that is usable in constant expressions at P ([expr.const]), or
  • N is an element of the set of potential results of an expression E, where
    • E is a discarded-value expression ([expr.context]) to which the lvalue-to-rvalue conversion is not applied, or
    • x is a non-volatile object that is usable in constant expressions at P and has no mutable subobjects, and
      • E is a class member access expression ([expr.ref]) naming a non-static data member of reference type and whose object expression has non-volatile-qualified type, or
      • the lvalue-to-rvalue conversion ([conv.lval]) is applied to E and E has non-volatile-qualified non-class type.
[Example 2: int f(int); int g(int&); struct A { int x; }; struct B { int& r; }; int h(bool cond) { constexpr A a = {1}; constexpr const volatile A& r = a; / odr-uses a int _ = f(cond ? a.x : r.x); / does not odr-use a or r int x, y; constexpr B b1 = {x}, b2 = {y}; / odr-uses x and y int _ = g(cond ? b1.r : b2.r); / does not odr-use b1 or b2 int _ = ((cond ? x : y), 0); / does not odr-use x or y return [] { return b1.r; / error: b1 is odr-used here because the object / referred to by b1.r is not constexpr-referenceable here }(); } — end example]
A structured binding is named by an expression if that expression is either an id-expression or a splice-expression that designates that structured binding.
A structured binding is odr-used if it is named by a potentially-evaluated expression.
*this is odr-used if this appears as a potentially-evaluated expression (including as the result of any implicit transformation to a class member access expression ([expr.prim.id.general])).
A virtual member function is odr-used if it is not pure.
A function is odr-used if it is named by a potentially-evaluated expression or conversion.
A non-placement allocation or deallocation function for a class is odr-used by the definition of a constructor of that class.
A non-placement deallocation function for a class is odr-used by the definition of the destructor of that class, or by being selected by the lookup at the point of definition of a virtual destructor ([class.dtor]).13
An assignment operator function in a class is odr-used by an implicitly-defined copy assignment or move assignment function for another class as specified in [class.copy.assign].
A constructor for a class is odr-used as specified in [dcl.init].
A destructor for a class is odr-used if it is potentially invoked.
A local entity ([basic.pre]) is odr-usable in a scope ([basic.scope.scope]) if
  • either the local entity is not *this, or an enclosing class or non-lambda function parameter scope exists and, if the innermost such scope is a function parameter scope, it corresponds to a non-static member function, and
  • for each intervening scope ([basic.scope.scope]) between the point at which the entity is introduced and the scope (where *this is considered to be introduced within the innermost enclosing class or non-lambda function parameter scope), either
If a local entity is odr-used in a scope in which it is not odr-usable, the program is ill-formed.
[Example 3: void f(int n) { [] { n = 1; }; / error: n is not odr-usable due to intervening lambda-expression struct A { void f() { n = 2; } / error: n is not odr-usable due to intervening function parameter scope }; void g(int = n); / error: n is not odr-usable due to intervening function parameter scope [=](int k = n) {}; / error: n is not odr-usable due to being / outside the block scope of the lambda-expression [&] { [n]{ return n; }; }; / OK } — end example]
[Example 4: void g() { constexpr int x = 1; auto lambda = [] <typename T, int = ((T)x, 0)> {}; / OK lambda.operator()<int, 1>(); / OK, does not consider x at all lambda.operator()<int>(); / OK, does not odr-use x lambda.operator()<const int&>(); / error: odr-uses x from a context where x is not odr-usable } void h() { constexpr int x = 1; auto lambda = [] <typename T> { (T)x; }; / OK lambda.operator()<int>(); / OK, does not odr-use x lambda.operator()<void>(); / OK, does not odr-use x lambda.operator()<const int&>(); / error: odr-uses x from a context where x is not odr-usable } — end example]
Every program shall contain at least one definition of every function or variable that is odr-used in that program outside of a discarded statement; no diagnostic required.
The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see [class.default.ctor], [class.copy.ctor], [class.dtor], and [class.copy.assign]).
[Example 5: auto f() { struct A {}; return A{}; } decltype(f() g(); auto x = g();
A program containing this translation unit is ill-formed because g is odr-used but not defined, and cannot be defined in any other translation unit because the local class A cannot be named outside this translation unit.
— end example]
A definition domain is a private-module-fragment or the portion of a translation unit excluding its private-module-fragment (if any).
A definition of an inline function or variable shall be reachable from the end of every definition domain in which it is odr-used outside of a discarded statement.
A definition of a class shall be reachable in every context in which the class is used in a way that requires the class type to be complete.
[Example 6: 
The following complete translation unit is well-formed, even though it never defines X: struct X; / declare X as a struct type struct X* x1; / use X in pointer formation X* x2; / use X in pointer formation
— end example]
[Note 3: 
The rules for declarations and expressions describe in which contexts complete class types are required.
A class type T must be complete if
— end note]
If a definable item D is defined in a translation unit by an injected declaration X ([expr.const]) and another translation unit contains a definition of D, that definition shall be an injected declaration having the same characteristic sequence as X; a diagnostic is required only if D is attached to a named module and a prior definition is reachable at the point where a later definition occurs.
For any other definable item D with definitions in multiple translation units,
  • if D is a non-inline non-templated function or variable, or
  • if the definitions in different translation units do not satisfy the following requirements,
the program is ill-formed; a diagnostic is required only if the definable item is attached to a named module and a prior definition is reachable at the point where a later definition occurs.
Given such an item, for all definitions of D, or, if D is an unnamed enumeration, for all definitions of D that are reachable at any given program point, the following requirements shall be satisfied.
  • Each such definition shall not be attached to a named module ([module.unit]).
  • Each such definition shall consist of the same sequence of tokens, where the definition of a closure type is considered to consist of the sequence of tokens of the corresponding lambda-expression.
  • In each such definition, corresponding names, looked up according to [basic.lookup], shall denote the same entity, after overload resolution ([over.match]) and after matching of partial template specializations ([temp.spec.partial.match]), except that a name can refer to
    • a non-volatile const object with internal or no linkage if the object or
    • a reference with internal or no linkage initialized with a constant expression such that the reference refers to the same object or function in all definitions of D.
  • In each such definition, except within the default arguments and default template arguments of D, corresponding lambda-expressions shall have the same closure type (see below).
  • In each such definition, corresponding entities shall have the same language linkage.
  • In each such definition, const objects with static or thread storage duration shall be constant-initialized if the object is constant-initialized in any such definition.
  • In each such definition, corresponding manifestly constant-evaluated expressions that are not value-dependent shall have the same value ([expr.const], [temp.dep.constexpr]).
  • In each such definition, the overloaded operators referred to, the implicit calls to conversion functions, constructors, operator new functions and operator delete functions, shall refer to the same function.
  • In each such definition, a default argument used by an (implicit or explicit) function call or a default template argument used by an (implicit or explicit) template-id, simple-template-id, or splice-specialization-specifier is treated as if its token sequence were present in the definition of D; that is, the default argument or default template argument is subject to the requirements described in this paragraph (recursively).
  • In each such definition, corresponding reflect-expressions ([expr.reflect]) compute equivalent values ([expr.eq]).
For the purposes of the preceding requirements:
  • If D is a class with an implicitly-declared constructor ([class.default.ctor], [class.copy.ctor]), it is as if the constructor was implicitly defined in every translation unit where it is odr-used, and the implicit definition in every translation unit shall call the same constructor for a subobject of D.
    [Example 7: / translation unit 1: struct X { X(int, int); X(int, int); }; X::X(int, int = 0) { } class D { X x = 0; }; D d1; / X(int, int) called by D() / translation unit 2: struct X { X(int, int); X(int, int); }; X::X(int, int = 0, int = 0) { } class D { X x = 0; }; D d2; / X(int, int, int) called by D(); / D()'s implicit definition violates the ODR — end example]
  • If D is a class with a defaulted three-way comparison operator function ([class.spaceship]), it is as if the operator was implicitly defined in every translation unit where it is odr-used, and the implicit definition in every translation unit shall call the same comparison operators for each subobject of D.
  • If D is a template and is defined in more than one translation unit, the requirements apply both to names from the template's enclosing scope used in the template definition, and also to dependent names at the point of instantiation ([temp.dep]).
These requirements also apply to corresponding entities defined within each definition of D (including the closure types of lambda-expressions, but excluding entities defined within default arguments or default template arguments of either D or an entity not defined within D).
For each such entity and for D itself, the behavior is as if there is a single entity with a single definition, including in the application of these requirements to other entities.
[Note 4: 
The entity is still declared in multiple translation units, and [basic.link] still applies to these declarations.
In particular, lambda-expressions ([expr.prim.lambda]) appearing in the type of D can result in the different declarations having distinct types, and lambda-expressions appearing in a default argument of D might still denote different types in different translation units.
— end note]
[Example 8: inline void f(bool cond, void (*p)() { if (cond) f(false, []{}); } inline void g(bool cond, void (*p)() = []{}) { if (cond) g(false); } struct X { void h(bool cond, void (*p)() = []{}) { if (cond) h(false); } };
If the definition of f appears in multiple translation units, the behavior of the program is as if there is only one definition of f.
If the definition of g appears in multiple translation units, the program is ill-formed (no diagnostic required) because each such definition uses a default argument that refers to a distinct lambda-expression closure type.
The definition of X can appear in multiple translation units of a valid program; the lambda-expressions defined within the default argument of X​::​h within the definition of X denote the same closure type in each translation unit.
— end example]
If, at any point in the program, there is more than one reachable unnamed enumeration definition in the same scope that have the same first enumerator name and do not have typedef names for linkage purposes ([dcl.enum]), those unnamed enumeration types shall be the same; no diagnostic required.
13)13)
An implementation is not required to call allocation and deallocation functions from constructors or destructors; however, this is a permissible implementation technique.
The declarations in a program appear in a number of scopes that are in general discontiguous.
The global scope contains the entire program; every other scope S is introduced by a declaration, parameter-declaration-clause, statement, handler, lambda-expression, or contract assertion (as described in the following subclauses of [basic.scope]) appearing in another scope, which thereby contains S.
An enclosing scope at a program point is any scope that contains it; the smallest such scope is said to be the immediate scope at that point.
A scope intervenes between a program point P and a scope S (that does not contain P) if it is or contains S but does not contain P.
Unless otherwise specified:
The host scope of a declaration is the inhabited scope if that scope is a block scope and the target scope otherwise.
An entity belongs to a scope S if S is the target scope of a declaration of the entity.
[Note 1: 
Special cases include that:
— end note]
Two non-static member functions have corresponding object parameters if
  • exactly one is an implicit object member function with no ref-qualifier and the types of their object parameters ([dcl.fct]), after removing references, are the same, or
  • their object parameters have the same type.
Two non-static member function templates have corresponding object parameters if
  • exactly one is an implicit object member function with no ref-qualifier and the types of their object parameters, after removing any references, are equivalent, or
  • the types of their object parameters are equivalent.
Two function templates have corresponding signatures if their template-parameter-lists have the same length, their corresponding template-parameters are equivalent, they have equivalent non-object-parameter-type-lists and return types (if any), and, if both are non-static members, they have corresponding object parameters.
Two declarations correspond if they (re)introduce the same name, both declare constructors, or both declare destructors, unless
  • either is a using-declarator, or
  • one declares a type (not a type alias) and the other declares a variable, non-static data member other than of an anonymous union ([class.union.anon]), enumerator, function, or function template, or
  • each declares a function or function template and they do not declare corresponding overloads.
Two function or function template declarations declare corresponding overloads if
[Note 2: 
Declarations can correspond even if neither binds a name.
[Example 1: struct A { friend void f(); / #1 }; struct B { friend void f() {} / corresponds to, and defines, #1 }; — end example]
— end note]
[Example 2: typedef int Int; enum E : int { a }; void f(int); / #1 void f(Int) {} / defines #1 void f(E) {} / OK, another overload struct X { static void f(); void f() const; / error: redeclaration void g(); void g() const; / OK void g() &; / error: redeclaration void h(this X&, int); void h(int) &&; / OK, another overload void j(this const X&); void j() const &; / error: redeclaration void k(); void k(this X&); / error: redeclaration }; — end example]
A declaration is name-independent if its name is _ (U+005f low line) and it declares
Recommended practice: Implementations should not emit a warning that a name-independent declaration is used or unused.
Two declarations potentially conflict if they correspond and cause their shared name to denote different entities ([basic.link]).
The program is ill-formed if, in any scope, a name is bound to two declarations A and B that potentially conflict and A precedes B ([basic.lookup]), unless B is name-independent.
[Note 3: 
An id-expression that names a unique name-independent declaration is usable until an additional declaration of the same name is introduced in the same scope ([basic.lookup.general]).
— end note]
[Note 4: 
Overload resolution can consider potentially conflicting declarations found in multiple scopes (e.g., via using-directives or for operator functions), in which case it is often ambiguous.
— end note]
[Example 3: void f() { int x,y; void x(); / error: different entity for x int y; / error: redefinition } enum { f }; / error: different entity for ​::​f namespace A {} namespace B = A; namespace B = A; / OK, no effect namespace B = B; / OK, no effect namespace A = B; / OK, no effect namespace B {} / error: different entity for B void g() { int _; _ = 0; / OK int _; / OK, name-independent declaration _ = 0; / error: two non-function declarations in the lookup set } void h () { int _; / #1 _ ++; / OK static int _; / error: conflicts with #1 because static variables are not name-independent } — end example]
A declaration is nominable in a class, class template, or namespace E at a point P if it precedes P, it does not inhabit a block scope, and its target scope is the scope associated with E or, if E is a namespace, any element of the inline namespace set of E ([namespace.def]).
[Example 4: namespace A { void f() {void g();} inline namespace B { struct S { friend void h(); static int i; }; } }
At the end of this example, the declarations of f, B, S, and h are nominable in A, but those of g and i are not.
— end example]
When instantiating a templated entity ([temp.pre]), any scope S introduced by any part of the template definition is considered to be introduced by the instantiated entity and to contain the instantiations of any declarations that inhabit S.
14)14)
An implicit object parameter ([over.match.funcs]) is not part of the parameter-type-list.

6.4.2 Point of declaration [basic.scope.pdecl]

The locus of a declaration ([basic.pre]) that is a declarator is immediately after the complete declarator ([dcl.decl]).
[Example 1: unsigned char x = 12; { unsigned char x = x; }
Here, the initialization of the second x has undefined behavior, because the initializer accesses the second x outside its lifetime ([basic.life]).
— end example]
[Note 1: 
A name from an outer scope remains visible up to the locus of the declaration that hides it.
[Example 2: 
const int i = 2; { int i[i]; } declares a block-scope array of two integers.
— end example]
— end note]
The locus of a class-specifier is immediately after the identifier or simple-template-id (if any) in its class-head ([class.pre]).
The locus of an enum-specifier is immediately after its enum-head; the locus of an opaque-enum-declaration is immediately after it ([dcl.enum]).
The locus of an alias-declaration is immediately after it.
The locus of a using-declarator that does not name a constructor is immediately after the using-declarator ([namespace.udecl]).
The locus of an enumerator-definition is immediately after it.
[Example 3: const int x = 12; { enum { x = x }; }
Here, the enumerator x is initialized with the value of the constant x, namely 12.
— end example]
[Note 2: 
After the declaration of a class member, the member name can be found in the scope of its class even if the class is an incomplete class.
[Example 4: struct X { enum E { z = 16 }; int b[X::z]; / OK }; — end example]
— end note]
The locus of an elaborated-type-specifier that is a declaration ([dcl.type.elab]) is immediately after it.
The locus of an injected-class-name declaration ([class.pre]) is immediately following the opening brace of the class definition.
The locus of the implicit declaration of a function-local predefined variable ([dcl.fct.def.general]) is immediately before the function-body of its function's definition.
The locus of the declaration of a structured binding ([dcl.struct.bind]) is immediately after the identifier-list of the structured binding declaration.
The locus of a for-range-declaration of a range-based for statement ([stmt.ranged]) is immediately after the for-range-initializer.
The locus of a for-range-declaration of an expansion-statement ([stmt.expand]) is immediately after the expansion-initializer.
The locus of a template-parameter is immediately after it.
[Example 5: typedef unsigned char T; template<class T = T / lookup finds the typedef-name , T / lookup finds the template parameter N = 0> struct A { }; — end example]
The locus of a result-name-introducer ([dcl.contract.res]) is immediately after it.
The locus of a concept-definition is immediately after its concept-name ([temp.concept]).
[Note 3:  — end note]
The locus of a namespace-definition with an identifier is immediately after the identifier.
[Note 4: 
An identifier is invented for an unnamed-namespace-definition ([namespace.unnamed]).
— end note]
[Note 5: 
Friend declarations can introduce functions or classes that belong to the nearest enclosing namespace or block scope, but they do not bind names anywhere ([class.friend]).
Function declarations at block scope and variable declarations with the extern specifier at block scope declare entities that belong to the nearest enclosing namespace, but they do not bind names in it.
— end note]
Each introduces a block scope that includes that statement or handler.
[Note 1: 
A substatement that is also a block has only one scope.
— end note]
A variable that belongs to a block scope is a block variable.
[Example 1: int i = 42; int a[10]; for (int i = 0; i < 10; i++) a[i] = i; int j = i; / j = 42 — end example]
If a declaration that is not a name-independent declaration and that binds a name in the block scope S of a potentially conflicts with a declaration whose target scope is the parent scope of S, the program is ill-formed.
[Example 2: if (int x = f() { int x; / error: redeclaration of x } else { int x; / error: redeclaration of x } — end example]

6.4.4 Function parameter scope [basic.scope.param]

[Note 1: 
A function parameter cannot be used for its value within the parameter-declaration-clause ([dcl.fct.default]).
— end note]
A lambda-expression E introduces a lambda scope that starts immediately after the lambda-introducer of E and extends to the end of the compound-statement of E.
Any namespace-definition for a namespace N introduces a namespace scope that includes the namespace-body for every namespace-definition for N.
For each non-friend redeclaration or specialization whose target scope is or is contained by the scope, the portion after the declarator-id, class-head-name, or enum-head-name is also included in the scope.
The global scope is the namespace scope of the global namespace ([basic.namespace]).
[Example 1: namespace Q { namespace V { void f(); } void V::f() { / in the scope of V void h(); / declares Q​::​V​::​h } } — end example]
Any declaration of a class or class template C introduces a class scope that includes the member-specification of the class-specifier for C (if any).
For each non-friend redeclaration or specialization whose target scope is or is contained by the scope, the portion after the declarator-id, class-head-name, or enum-head-name is also included in the scope.
[Note 1: 
Lookup from a program point before the class-specifier of a class will find no bindings in the class scope.
[Example 1: template<class D> struct B { D::type x; / #1 }; struct A { using type = int; }; struct C : A, B<C> {}; / error at #1: C​::​type not found — end example]
— end note]

6.4.8 Enumeration scope [basic.scope.enum]

Any declaration of an enumeration E introduces an enumeration scope that includes the enumerator-list of the enum-specifier for E (if any).

6.4.9 Template parameter scope [basic.scope.temp]

Each template-declaration D introduces a template parameter scope that extends from the beginning of its template-parameter-list to the end of the template-declaration.
Any declaration outside the template-parameter-list that would inhabit that scope instead inhabits the same scope as D.
The parent scope of any scope S that is not a template parameter scope is the smallest scope that contains S and is not a template parameter scope.
[Note 1: 
Therefore, only template parameters belong to a template parameter scope, and only template parameter scopes have a template parameter scope as a parent scope.
— end note]

6.4.10 Contract-assertion scope [basic.scope.contract]

Each contract assertion ([basic.contract]) C introduces a contract-assertion scope that includes C.
If a result-name-introducer ([dcl.contract.res]) that is not name-independent ([basic.scope.scope]) and whose enclosing postcondition assertion is associated with a function F potentially conflicts with a declaration whose target scope is the program is ill-formed.

6.5 Name lookup [basic.lookup]

Name lookup associates the use of a name with a set of declarations ([basic.def]) of that name.
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.
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 type alias 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 type alias and of its underlying entity are found, the declaration of the type alias is discarded instead of the type declaration.

6.5.2 Member name lookup [class.member.lookup]

A search in a scope X for a name M from a program point P is a single search in X for M from P unless X is the scope of a class or class template T, in which case the following steps define the result of the search.
[Note 1: 
The result differs only if M is a conversion-function-id or if the single search would find nothing.
— end note]
The lookup set for a name N in a class or class template C, called S(N,C), consists of two component sets: the declaration set, a set of members named N; and the subobject set, a set of subobjects where declarations of these members were found (possibly via using-declarations).
In the declaration set, type declarations (including injected-class-names) are replaced by the types they designate.
S(N,C) is calculated as follows:
The declaration set is the result of a single search in the scope of C for N from immediately after the class-specifier of C if P is in a complete-class context of C or from P otherwise.
If the resulting declaration set is not empty, the subobject set contains C itself, and calculation is complete.
Otherwise (i.e., C does not contain a declaration of N or the resulting declaration set is empty), S(N,C) is initially empty.
Calculate the lookup set for N in each direct non-dependent ([temp.dep.type]) base class subobject
[Note 2: 
If C is incomplete, only base classes whose base-specifier appears before P are considered.
If C is an instantiated class, its base classes are not dependent.
— end note]
The following steps define the result of merging lookup set
  • If each of the subobject members of
    Conversely, if each of the subobject members of S(N,C) is a base class subobject of at least one of the subobject members of
  • Otherwise, if the declaration sets of
    In subsequent merges, an invalid declaration set is considered different from any other.
  • Otherwise, the new S(N,C) is a lookup set with the shared set of declarations and the union of the subobject sets.
The result of the search is the declaration set of S(M,T).
If it is an invalid set, the program is ill-formed.
If it differs from the result of a search in T for M in a complete-class context ([class.mem]) of T, the program is ill-formed, no diagnostic required.
[Example 1: struct A { int x; }; / S(x,A) = { { A​::​x }, { A } } struct B { float x; }; / S(x,B) = { { B​::​x }, { B } } struct C: public A, public B { }; / S(x,C) = { invalid, { A in C, B in C } } struct D: public virtual C { }; / S(x,D) = S(x,C) struct E: public virtual C { char x; }; / S(x,E) = { { E​::​x }, { E } } struct F: public D, public E { }; / S(x,F) = S(x,E) int main() { F f; f.x = 0; / OK, lookup finds E​::​x }
S(x,F) is unambiguous because the A and B base class subobjects of D are also base class subobjects of E, so S(x,D) is discarded in the first merge step.
— end example]
If M is a non-dependent conversion-function-id, conversion function templates that are members of T are considered.
For each such template F, the lookup set S(t,T) is constructed, considering a function template declaration to have the name t only if it corresponds to a declaration of F ([basic.scope.scope]).
The members of the declaration set of each such lookup set, which shall not be an invalid set, are included in the result.
[Note 3: 
Overload resolution will discard those that cannot convert to the type specified by M ([temp.over]).
— end note]
[Note 4: 
A static member, a nested type or an enumerator defined in a base class T can unambiguously be found even if an object has more than one base class subobject of type T.
Two base class subobjects share the non-static member subobjects of their common virtual base classes.
— end note]
[Example 2: struct V { int v; }; struct A { int a; static int s; enum { e }; }; struct B : A, virtual V { }; struct C : A, virtual V { }; struct D : B, C { }; void f(D* pd) { pd->v++; / OK, only one v (virtual) pd->s++; / OK, only one s (static) int i = pd->e; / OK, only one e (enumerator) pd->a++; / error: ambiguous: two as in D } — end example]
[Note 5: 
When virtual base classes are used, a hidden declaration can be reached along a path through the subobject lattice that does not pass through the hiding declaration.
This is not an ambiguity.
The identical use with non-virtual base classes is an ambiguity; in that case there is no unique instance of the name that hides all the others.
— end note]
[Example 3: struct V { int f(); int x; }; struct W { int g(); int y; }; struct B : virtual V, W { int f(); int x; int g(); int y; }; struct C : virtual V, W { }; struct D : B, C { void glorp(); };
virt W1 W V V W2 W B B B->W1 B->V C C C->V C->W2 D D D->B D->C
Figure 1 — Name lookup  [fig:class.lookup]
As illustrated in Figure 1, the names declared in V and the left-hand instance of W are hidden by those in B, but the names declared in the right-hand instance of W are not hidden at all.
void D::glorp() { x++; / OK, B​::​x hides V​::​x f(); / OK, B​::​f() hides V​::​f() y++; / error: B​::​y and C's W​::​y g(); / error: B​::​g() and C's W​::​g() } — end example]
An explicit or implicit conversion from a pointer to or an expression designating an object of a derived class to a pointer or reference to one of its base classes shall unambiguously refer to a unique object representing the base class.
[Example 4: struct V { }; struct A { }; struct B : A, virtual V { }; struct C : A, virtual V { }; struct D : B, C { }; void g() { D d; B* pb = &d; A* pa = &d; / error: ambiguous: C's A or B's A? V* pv = &d; / OK, only one V subobject } — end example]
[Note 6: 
Even if the result of name lookup is unambiguous, use of a name found in multiple subobjects might still be ambiguous ([conv.mem], [expr.ref], [class.access.base]).
— end note]
[Example 5: struct B1 { void f(); static void f(int); int i; }; struct B2 { void f(double); }; struct I1: B1 { }; struct I2: B1 { }; struct D: I1, I2, B2 { using B1::f; using B2::f; void g() { f(); / Ambiguous conversion of this f(0); / Unambiguous (static) f(0.0); / Unambiguous (only one B2) int B1::* mpB1 = &D::i; / Unambiguous int D::* mpD = &D::i; / Ambiguous conversion } }; — end example]

6.5.3 Unqualified name lookup [basic.lookup.unqual]

A using-directive is active in a scope S at a program point P if it precedes P and inhabits either S or the scope of a namespace nominated by a using-directive that is active in S at P.
An unqualified search in a scope S from a program point P includes the results of searches from P in
  • S, and
  • for any scope U that contains P and is or is contained by S, each namespace contained by S that is nominated by a using-directive that is active in U at P.
If no declarations are found, the results of the unqualified search are the results of an unqualified search in the parent scope of S, if any, from P.
[Note 1: 
When a class scope is searched, the scopes of its base classes are also searched ([class.member.lookup]).
If it inherits from a single base, it is as if the scope of the base immediately contains the scope of the derived class.
Template parameter scopes that are associated with one scope in the chain of parents are also considered ([temp.local]).
— end note]
Unqualified name lookup from a program point performs an unqualified search in its immediate scope.
An unqualified name is a name that does not immediately follow a nested-name-specifier or the . or -> in a class member access expression ([expr.ref]), possibly after a template keyword or ~.
Unless otherwise specified, such a name undergoes unqualified name lookup from the point where it appears.
An unqualified name that is a component name ([expr.prim.id.unqual]) of a type-specifier or ptr-operator of a conversion-type-id is looked up in the same fashion as the conversion-function-id in which it appears.
If that lookup finds nothing, it undergoes unqualified name lookup; in each case, only names that denote types or templates whose specializations are types are considered.
[Example 1: struct T1 { struct U { int i; }; }; struct T2 { }; struct U1 {}; struct U2 {}; struct B { using T = T1; using U = U1; operator U1 T1::*(); operator U1 T2::*(); operator U2 T1::*(); operator U2 T2::*(); }; template<class X, class T> int g() { using U = U2; X().operator U T::*(); / #1, searches for T in the scope of X first X().operator U decltype(T()::*(); / #2 return 0; } int x = g<B, T2>(); / #1 calls B​::​operator U1 T1​::​* / #2 calls B​::​operator U1 T2​::​* — end example]
In a friend declaration declarator whose declarator-id is a qualified-id whose lookup context ([basic.lookup.qual]) is a class or namespace S, lookup for an unqualified name that appears after the declarator-id performs a search in the scope associated with S.
If that lookup finds nothing, it undergoes unqualified name lookup.
[Example 2: using I = int; using D = double; namespace A { inline namespace N {using C = char; } using F = float; void f(I); void f(D); void f(C); void f(F); } struct X0 {using F = float; }; struct W { using D = void; struct X : X0 { void g(I); void g(::D); void g(F); }; }; namespace B { typedef short I, F; class Y { friend void A::f(I); / error: no void A​::​f(short) friend void A::f(D); / OK friend void A::f(C); / error: A​::​N​::​C not found friend void A::f(F); / OK friend void W::X::g(I); / error: no void X​::​g(short) friend void W::X::g(D); / OK friend void W::X::g(F); / OK }; } — end example]

6.5.4 Argument-dependent name lookup [basic.lookup.argdep]

When the postfix-expression in a function call ([expr.call]) is an unqualified-id, and unqualified lookup ([basic.lookup.unqual]) for the name in the unqualified-id does not find any
  • declaration of a class member, or
  • function declaration inhabiting a block scope, or
  • declaration not of a function or function template
then lookup for the name also includes the result of argument-dependent lookup in a set of associated namespaces that depends on the types of the arguments (and for type template template arguments, the namespace of the template argument), as specified below.
[Example 1: namespace N { struct S { }; void f(S); } void g() { N::S s; f(s); / OK, calls N​::​f (f)(s); / error: N​::​f not considered; parentheses prevent argument-dependent lookup } — end example]
[Note 1: 
For purposes of determining (during parsing) whether an expression is a postfix-expression for a function call, the usual name lookup rules apply.
In some cases a name followed by < is treated as a template-name even though name lookup did not find a template-name (see [temp.names]).
For example, int h; void g(); namespace N { struct A {}; template <class T> int f(T); template <class T> int g(T); template <class T> int h(T); } int x = f<N::A>(N::A(); / OK, lookup of f finds nothing, f treated as template name int y = g<N::A>(N::A(); / OK, lookup of g finds a function, g treated as template name int z = h<N::A>(N::A(); / error: h< does not begin a template-id
The rules have no effect on the syntactic interpretation of an expression.
For example, typedef int f; namespace N { struct A { friend void f(A &); operator int(); void g(A a) { int i = f(a); / f is the typedef, not the friend function: equivalent to int(a) } }; }
Because the expression is not a function call, argument-dependent name lookup does not apply and the friend function f is not found.
— end note]
For each argument type T in the function call, there is a set of zero or more associated entities to be considered.
The set of entities is determined entirely by the types of the function arguments (and any type template template arguments).
Any typedef-names and using-declarations used to specify the types do not contribute to this set.
The set of entities is determined in the following way:
  • If T is std​::​meta​::​info ([meta.syn]), its associated set of entities is the singleton containing the enumeration type std​::​meta​::​operators ([meta.reflection.operators]).
    [Note 2: 
    The std​::​meta​::​info type is a type alias, so an explicit rule is needed to associate calls whose arguments are reflections with the namespace std​::​meta.
    — end note]
  • If T is any other fundamental type, its associated set of entities is empty.
  • If T is a class type (including unions), its associated entities are: the class itself; the class of which it is a member, if any; and, if it is a complete type, its direct and indirect base classes.
    Furthermore, if T is a class template specialization, its associated entities also include: the entities associated with the types of the template arguments provided for template type parameters; the templates used as type template template arguments; and the classes of which any member templates used as type template template arguments are members.
    [Note 3: 
    Constant template arguments, variable template template arguments, and concept template arguments do not contribute to the set of associated entities.
    — end note]
  • If T is an enumeration type, its associated entities are T and, if it is a class member, the member's class.
  • If T is a pointer to U or an array of U, its associated entities are those associated with U.
  • If T is a function type, its associated entities are those associated with the function parameter types and those associated with the return type.
  • If T is a pointer to a member function of a class X, its associated entities are those associated with the function parameter types and return type, together with those associated with X.
  • If T is a pointer to a data member of class X, its associated entities are those associated with the member type together with those associated with X.
In addition, if the argument is an overload set or the address of such a set, its associated entities are the union of those associated with each of the members of the set, i.e., the entities associated with its parameter types and return type.
Additionally, if the aforementioned overload set is named with a template-id, its associated entities also include its template template arguments and those associated with its type template arguments.
The associated namespaces for a call are the innermost enclosing non-inline namespaces for its associated entities as well as every element of the inline namespace set ([namespace.def]) of those namespaces.
Argument-dependent lookup finds all declarations of functions and function templates that
  • are found by a search of any associated namespace, or
  • are declared as a friend ([class.friend]) of any class with a reachable definition in the set of associated entities, or
  • are exported, are attached to a named module M ([module.interface]), do not appear in the translation unit containing the point of the lookup, and have the same innermost enclosing non-inline namespace scope as a declaration of an associated entity attached to M ([basic.link]).
If the lookup is for a dependent name ([temp.dep], [temp.dep.candidate]), the above lookup is also performed from each point in the instantiation context ([module.context]) of the lookup, additionally ignoring any declaration that appears in another translation unit, is attached to the global module, and is either discarded ([module.global.frag]) or has internal linkage.
[Example 2: 

Translation unit #1:export module M; namespace R { export struct X {}; export void f(X); } namespace S { export void f(R::X, R::X); }

Translation unit #2:export module N; import M; export R::X make(); namespace R { static int g(X); } export template<typename T, typename U> void apply(T t, U u) { f(t, u); g(t); }

Translation unit #3:module Q; import N; namespace S { struct Z { template<typename T> operator T(); }; } void test() { auto x = make(); / OK, decltype(x) is R​::​X in module M R::f(x); / error: R and R​::​f are not visible here f(x); / OK, calls R​::​f from interface of M f(x, S::Z(); / error: S​::​f in module M not considered / even though S is an associated namespace apply(x, S::Z(); / error: S​::​f is visible in instantiation context, but / R​::​g has internal linkage and cannot be used outside TU #2 } — end example]

[Note 4: 
The set of associated namespaces can include namespaces already considered by ordinary unqualified lookup.
— end note]
[Example 3: namespace NS { class T { }; void f(T); void g(T, int); } NS::T parm; void g(NS::T, float); int main() { f(parm); / OK, calls NS​::​f extern void g(NS::T, float); g(parm, 1); / OK, calls g(NS​::​T, float) } — end example]

6.5.5 Qualified name lookup [basic.lookup.qual]

Lookup of an identifier followed by a ​::​ scope resolution operator considers only namespaces, types, and templates whose specializations are types.
If a name, template-id, splice-scope-specifier, or computed-type-specifier is followed by a ​::​, it shall either be a dependent splice-scope-specifier ([temp.dep.splice]) or it shall designate a namespace, class, enumeration, or dependent type, and the ​::​ is never interpreted as a complete nested-name-specifier.
[Example 1: class A { public: static int n; }; int main() { int A; A::n = 42; / OK A b; / error: A does not name a type } template<int> struct B : A {}; namespace N { template<int> void B(); int f() { return B<0>::n; / error: N​::​B<0> is not a type } } — end example]
A member-qualified name is the (unique) component name ([expr.prim.id.unqual]), if any, of in the id-expression of a class member access expression ([expr.ref]).
The lookup context of a member-qualified name is the type of its associated object expression (considered dependent if the object expression is type-dependent).
The lookup context of any other qualified name is the type, template, or namespace nominated by the preceding nested-name-specifier.
[Note 1: 
When parsing a class member access, the name following the -> or . is a qualified name even though it is not yet known of which kind.
— end note]
[Example 2: 
In N::C::m.Base::f() Base is a member-qualified name; the other qualified names are C, m, and f.
— end example]
Qualified name lookup in a class, namespace, or enumeration performs a search of the scope associated with it ([class.member.lookup]) except as specified below.
Unless otherwise specified, a qualified name undergoes qualified name lookup in its lookup context from the point where it appears unless the lookup context either is dependent and is not the current instantiation ([temp.dep.type]) or is not a class or class template.
If nothing is found by qualified lookup for a member-qualified name that is the terminal name ([expr.prim.id.unqual]) of a nested-name-specifier and is not dependent, it undergoes unqualified lookup.
[Note 2: 
During lookup for a template specialization, no names are dependent.
— end note]
[Example 3: int f(); struct A { int B, C; template<int> using D = void; using T = void; void f(); }; using B = A; template<int> using C = A; template<int> using D = A; template<int> using X = A; template<class T> void g(T *p) { / as instantiated for g<A>: p->X<0>::f(); / error: A​::​X not found in ((p->X) < 0) > ​::​f() p->template X<0>::f(); / OK, ​::​X found in definition context p->B::f(); / OK, non-type A​::​B ignored p->template C<0>::f(); / error: A​::​C is not a template p->template D<0>::f(); / error: A​::​D<0> is not a class type p->T::f(); / error: A​::​T is not a class type } template void g(A*); — end example]
If a qualified name Q follows a ~:
  • If Q is a member-qualified name, it undergoes unqualified lookup as well as qualified lookup.
  • Otherwise, its nested-name-specifier N shall nominate a type.
    If N has another nested-name-specifier S, Q is looked up as if its lookup context were that nominated by S.
  • Otherwise, if the terminal name of N is a member-qualified name M, Q is looked up as if ~Q appeared in place of M (as above).
  • Otherwise, Q undergoes unqualified lookup.
  • Each lookup for Q considers only types (if Q is not followed by a <) and templates whose specializations are types.
    If it finds nothing or is ambiguous, it is discarded.
  • The type-name that is or contains Q shall refer to its (original) lookup context (ignoring cv-qualification) under the interpretation established by at least one (successful) lookup performed.
[Example 4: struct C { typedef int I; }; typedef int I1, I2; extern int* p; extern int* q; void f() { p->C::I::~I(); / I is looked up in the scope of C q->I1::~I2(); / I2 is found by unqualified lookup } struct A { ~A(); }; typedef A AB; int main() { AB* p; p->AB::~AB(); / explicitly calls the destructor for A } — end example]

6.5.5.2 Class members [class.qual]

In a lookup for a qualified name N whose lookup context is a class C in which function names are not ignored,15 N is instead considered to name the constructor of class C.
Such a constructor name shall be used only in the declarator-id of a (friend) declaration of a constructor or in a using-declaration.
[Example 1: struct A { A(); }; struct B: public A { B(); }; A::A() { } B::B() { } B::A ba; / object of type A A::A a; / error: A​::​A is not a type name struct A::A a2; / object of type A — end example]
15)15)
Lookups in which function names are ignored include names appearing in a nested-name-specifier, an elaborated-type-specifier, or a base-specifier.

6.5.5.3 Namespace members [namespace.qual]

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

6.5.6 Elaborated type specifiers [basic.lookup.elab]

If the class-key or enum keyword in an elaborated-type-specifier is followed by an identifier that is not followed by ​::​, lookup for the identifier is type-only ([basic.lookup.general]).
[Note 1: 
In general, the recognition of an elaborated-type-specifier depends on the following tokens.
If the identifier is followed by ​::​, see [basic.lookup.qual].
— end note]
If the terminal name of an elaborated-type-specifier is a qualified name, lookup for it is type-only.
If the name lookup does not find a previously declared type-name, the elaborated-type-specifier is ill-formed.
[Example 1: struct Node { struct Node* Next; / OK, refers to injected-class-name Node struct Data* Data; / OK, declares type Data at global scope and member Data }; struct Data { struct Node* Node; / OK, refers to Node at global scope friend struct ::Glob; / error: Glob is not declared, cannot introduce a qualified type ([dcl.type.elab]) friend struct Glob; / OK, refers to (as yet) undeclared Glob at global scope. /* ... */ }; struct Base { struct Data; / OK, declares nested Data struct ::Data* thatData; / OK, refers to ​::​Data struct Base::Data* thisData; / OK, refers to nested Data friend class ::Data; / OK, global Data is a friend friend class Data; / OK, nested Data is a friend struct Data { /* ... */ }; / Defines nested Data }; struct Data; / OK, redeclares Data at global scope struct ::Data; / error: cannot introduce a qualified type ([dcl.type.elab]) struct Base::Data; / error: cannot introduce a qualified type ([dcl.type.elab]) struct Base::Datum; / error: Datum undefined struct Base::Data* pBase; / OK, refers to nested Data — end example]

6.5.7 Using-directives and namespace aliases [basic.lookup.udir]

In a using-directive or namespace-alias-definition, during the lookup for a namespace-name or for a name in a nested-name-specifier only namespace names are considered.

6.6 Splice specifiers [basic.splice]

The constant-expression of a splice-specifier shall be a converted constant expression of type std​::​meta​::​info ([expr.const]).
A splice-specifier whose converted constant-expression represents a construct X is said to designate either
[Note 1: 
A splice-specifier is dependent if the converted constant-expression is value-dependent ([temp.dep.splice]).
— end note]
A non-dependent splice-specifier of a splice-specialization-specifier shall designate a template.
[Note 2: 
A < following a splice-specifier is interpreted as the delimiter of a template-argument-list when the splice-specifier is preceded by the keyword template or the keyword typename, or when it appears in a type-only context ([temp.names]).
[Example 1: constexpr int v = 1; template<int V> struct TCls { static constexpr int s = V + 1; }; using alias = [:^TCls:]<([:^v:])>; / OK, a splice-specialization-specifier with a parenthesized splice-expression as a template argument static_assert(alias::s == 2); auto o1 = [:^TCls:]<([:^v:])>(); / error: < means less than auto o2 = typename [:^TCls:]<([:^v:])>(); / OK, o2 is an object of type TCls<1> consteval int bad_splice(std::meta::info v) { return [:v:]; / error: v is not constant } — end example]
— end note]