[basic.scope.scope] (original) (raw)

6 Basics [basic]

6.4.1 General [basic.scope.scope]

The declarations in a program appear in a number of scopesthat 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, 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 scopeat that point.

A scope intervenesbetween 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 Sif S is the target scope of a declaration of the entity.

[Note 1:

Special cases include that:

— _end note_]

Two non-static member functions havecorresponding object parameters if

Two non-static member function templates havecorresponding object parameters if

Two function templates havecorresponding signatures if their template-parameter-list_s_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 correspondif they (re)introduce the same name, both declare constructors, or both declare destructors, unless

Two function or function template declarations declarecorresponding overloads if

[Note 2:

Declarations can correspond even if neither binds a name.

[Example 1: struct A { friend void f(); };struct B { friend void f() {} }; — _end example_]

— _end note_]

[Example 2: typedef int Int;enum E : int { a };void f(int); void f(Int) {} void f(E) {} struct X { static void f();void f() const; void g();void g() const; void g() &; void h(this X&, int);void h(int) &&; void j(this const X&);void j() const &; void k();void k(this X&); }; — _end example_]

A declaration is name-independentif 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 conflictif 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 Bthat 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(); int y; } enum { f }; namespace A {} namespace B = A;namespace B = A; namespace B = B; namespace A = B; namespace B {} void g() { int _; _ = 0; int _; _ = 0; } void h () { int _; _ ++; static int _; } — _end example_]

A declaration is nominablein 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 hare 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.