cpp/language/scope

Each that appears in a C++ program is only visible in some possibly discontiguous portion of the source code called its scope.

Within a scope, can be used to associate the name with its declaration.

Block scope
The potential scope of a name declared in a begins at the point of declaration and ends at the end of the block. Actual scope is the same as potential scope unless an identical name is declared in a nested block, in which case the potential scope of the name in the nested block is excluded from the actual scope of the name in the enclosing block.

The potential scope of a name declared in an exception handler begins at the point of declaration and ends at the end of the exception handler, and is not in scope in another exception handler or in the enclosing block.

The potential scope of a name declared in the init-statement of a, in the condition of a , in the range_declaration of a , in the condition of an , , or begins at the point of declaration and ends at the end of the controlled statement.

Function parameter scope
The potential scope of a name declared in a function parameter (including parameters of a lambda expression) or of a function-local predefined variable begins at the point of declaration.
 * If the enclosing function declarator is not the declarator of a function definition, its potential scope ends at the end of that function declarator.
 * Otherwise, its potential scope ends at the end of the last exception handler of the, or at the end of the function body if a function try block was not used.

Namespace scope
The potential scope of a name declared in a begins at the point of declaration and includes the rest of the namespace and all namespace definitions with an identical namespace name that follow, plus, for any  that introduced this name or its entire namespace into another scope, the rest of that scope.

The top-level scope of a translation unit ("file scope" or "global scope") is also a namespace and is properly called "global namespace scope". The potential scope of a name declared in the global namespace scope begins at the point of declaration and ends at the end of the translation unit.

The potential scope of a name declared in an unnamed namespace or in an inline namespace includes the potential scope that name would have if it were declared in the enclosing namespace.

Class scope
The potential scope of a name declared in a begins at the point of declaration and includes the rest of the class body, all the derived classes bodies, the function bodies (even if defined outside the class definition or before the declaration of the name), function default arguments, function exception specifications, in-class brace-or-equal initializers, and all these things in nested classes, recursively.

{{source|1= struct X { int f(int a = n) { // n is in scope in function default argument return a * n; // n is in scope in function body }   using r = int; r g; int i = n * 2; // n is in scope in initializer // int x[n]; // error: n is not in scope in class body static const int n = 1; // scope of n begins int x[n]; // OK: n is now in scope in class body }; // scope of n pauses

struct Y: X { // scope of n resumes int y[n]; // n is in scope }; // scope of n ends

//r X::g {    // error: r is not in scope outside out-of-class function body auto X::g->r { // OK: trailing return type r is in scope return n;   // n is in scope in out-of-class function body } }}

If a name is used in a class body before it is declared, and another declaration for that name is in scope, the program is.

Names of class members can be used in the following contexts:
 * in its own class scope or in the class scope of a derived class;
 * after the operator applied to an expression of the type of its class or a class derived from it;
 * after the operator applied to an expression of the type of pointer to its class or pointers to a class derived from it;
 * after the operator applied to the name of its class or the name of a class derived from it.

Enumeration scope
The potential scope of an enumerator of an begins at the point of declaration and ends at the end of the enclosing scope.

The potential scope of an enumerator of a begins at the point of declaration and ends at the end of the enum specifier.

Template parameter scope
The potential scope of a template parameter name begins at the point of declaration and ends at the end of the smallest template declaration in which it was introduced. In particular, a template parameter can be used in the declarations of subsequent template parameters and in the specifications of base classes, but can't be used in the declarations of the preceding template parameters.

The potential scope of the name of the parameter of a template template parameter is the smallest template parameter list in which that name appears.

Similar to other nested scopes, the name of a template parameter hides the same name from the enclosing scope for the duration of its own.

Point of declaration
In general, a name is visible after the locus of its first declaration, which is located as follows.

The locus of a name declared in a simple declaration is immediately after that name's and before its initializer, if any.

The locus of a class or class template declaration is immediately after the identifier that names the class (or the that names the template specialization) in its. The class or class template name is already in scope in the list of base classes.

The locus of or opaque enum declaration is immediately after the identifier that names the enumeration.

The locus of a declaration is immediately after the type-id to which the alias refers.

The locus for a declarator in a that does not name a constructor is immediately after the declarator.

The locus of an enumerator is immediately after its definition (not before the initializer as it is for variables).

The locus for an is immediately following the opening brace of its class (or class template) definition.

The locus of a is immediately after its complete template parameter (including the optional default argument).

The locus of a named is immediately after the namespace name.