6 Basics [basic]

6.4 Scope [basic.scope]

6.4.2 Point of declaration [basic.scope.pdecl]

The point of declaration for a name is immediately after its complete declarator ([dcl.decl]) and before its initializer (if any), except as noted below.
[Example
:
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
:
A name from an outer scope remains visible up to the point of declaration of the name that hides it.
[Example
:
const int  i = 2;
{ int  i[i]; }
declares a block-scope array of two integers.
— end example
]
— end note
]
The point of declaration for a class or class template first declared by a class-specifier is immediately after the identifier or simple-template-id (if any) in its class-head.
The point of declaration for an enumeration is immediately after the identifier (if any) in either its enum-specifier or its first opaque-enum-declaration, whichever comes first.
The point of declaration of an alias or alias template immediately follows the defining-type-id to which the alias refers.
The point of declaration of a using-declarator that does not name a constructor is immediately after the using-declarator.
The point of declaration for an enumerator is immediately after its enumerator-definition.
[Example
:
const int x = 12;
{ enum { x = x }; }
Here, the enumerator x is initialized with the value of the constant x, namely 12.
— end example
]
After the point of declaration of a class member, the member name can be looked up in the scope of its class.
[Note
:
This is true even if the class is an incomplete class.
For example,
struct X {
  enum E { z = 16 };
  int b[X::z];      // OK
};
— end note
]
The point of declaration of a class first declared in an elaborated-type-specifier is as follows:
The point of declaration for an injected-class-name ([class.pre]) is immediately following the opening brace of the class definition.
The point of declaration for a function-local predefined variable ([dcl.fct.def.general]) is immediately before the function-body of a function definition.
The point of declaration of a structured binding ([dcl.struct.bind]) is immediately after the identifier-list of the structured binding declaration.
The point of declaration for the variable or the structured bindings declared in the for-range-declaration of a range-based for statement ([stmt.ranged]) is immediately after the for-range-initializer.
The point of declaration for a template parameter is immediately after its complete template-parameter.
[Example
:
typedef unsigned char T;
template<class T
  = T               // lookup finds the typedef name of unsigned char
  , T               // lookup finds the template parameter
    N = 0> struct A { };
— end example
]
[Note
:
Friend declarations refer to functions or classes that are members of the nearest enclosing namespace, but they do not introduce new names into that namespace ([namespace.memdef]).
Function declarations at block scope and variable declarations with the extern specifier at block scope refer to declarations that are members of an enclosing namespace, but they do not introduce new names into that scope.
— end note
]
[Note
:
For point of instantiation of a template, see [temp.point].
— end note
]