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 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, except when
    • both declare functions with the same non-object-parameter-type-list,19 equivalent ([temp.over.link]) trailing requires-clauses (if any, except as specified in [temp.friend]), and, if both are non-static members, they have corresponding object parameters, or
    • both declare function templates with equivalent non-object-parameter-type-lists, return types (if any), template-heads, and trailing requires-clauses (if any), and, if both are non-static members, they have corresponding object parameters.
[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]
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 that potentially conflict and one precedes the other ([basic.lookup]).
[Note 3:
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 — 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.
19)19)
An implicit object parameter ([over.match.funcs]) is not part of the parameter-type-list.