6 Basics [basic]

6.4 Scope [basic.scope]

6.4.1 General [basic.scope.scope]

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, or handler (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:
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 top-level 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 typedef-name) 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.
17)17)
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 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 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]
[Note 6: 
For point of instantiation of a template, see [temp.point].
— end note]

6.4.3 Block scope [basic.scope.block]

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]

6.4.5 Lambda scope [basic.scope.lambda]

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.

6.4.6 Namespace scope [basic.scope.namespace]

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]

6.4.7 Class scope [basic.scope.class]

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 template-parameter introduces a template parameter scope that includes the template-head of the template-parameter.
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]