290 lines
13 KiB
Markdown
290 lines
13 KiB
Markdown
[basic.scope.scope]
|
||
|
||
# 6 Basics [[basic]](./#basic)
|
||
|
||
## 6.4 Scope [[basic.scope]](basic.scope#scope)
|
||
|
||
### 6.4.1 General [basic.scope.scope]
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L939)
|
||
|
||
The declarations in a program appear in a number of [*scopes*](#def:scope "6.4.1 General [basic.scope.scope]") that are in general discontiguous[.](#1.sentence-1)
|
||
|
||
The [*global scope*](#def:scope,global "6.4.1 General [basic.scope.scope]") contains the entire program;
|
||
every other scope S is introduced by a
|
||
declaration,[*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]"),[*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]"),[*handler*](except.pre#nt:handler "14.1 Preamble [except.pre]"), or
|
||
contract assertion
|
||
(as described in the following subclauses of [[basic.scope]](basic.scope "6.4 Scope"))
|
||
appearing in another scope, which thereby contains S[.](#1.sentence-2)
|
||
|
||
An [*enclosing scope*](#def:scope,enclosing "6.4.1 General [basic.scope.scope]") at a program point is any scope that contains it;
|
||
the smallest such scope is said to be the [*immediate scope*](#def:scope,immediate "6.4.1 General [basic.scope.scope]") at that point[.](#1.sentence-3)
|
||
|
||
A scope [*intervenes*](#def:scope,intervene "6.4.1 General [basic.scope.scope]") 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[.](#1.sentence-4)
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L958)
|
||
|
||
Unless otherwise specified:
|
||
|
||
- [(2.1)](#2.1)
|
||
|
||
The smallest scope that contains a scope S is
|
||
the [*parent scope*](#def:scope,parent "6.4.1 General [basic.scope.scope]") of S[.](#2.1.sentence-1)
|
||
|
||
- [(2.2)](#2.2)
|
||
|
||
No two declarations (re)introduce the same entity[.](#2.2.sentence-1)
|
||
|
||
- [(2.3)](#2.3)
|
||
|
||
A declaration [*inhabits*](#def:scope,inhabit "6.4.1 General [basic.scope.scope]") the immediate scope at its locus ([[basic.scope.pdecl]](basic.scope.pdecl "6.4.2 Point of declaration"))[.](#2.3.sentence-1)
|
||
|
||
- [(2.4)](#2.4)
|
||
|
||
A declaration's [*target scope*](#def:scope,target "6.4.1 General [basic.scope.scope]") is the scope it inhabits[.](#2.4.sentence-1)
|
||
|
||
- [(2.5)](#2.5)
|
||
|
||
Any names (re)introduced by a declaration are [*bound*](#def:name,bound "6.4.1 General [basic.scope.scope]") to it
|
||
in its target scope[.](#2.5.sentence-1)
|
||
|
||
The [*host scope*](#def:scope,host "6.4.1 General [basic.scope.scope]") of a declaration is
|
||
the inhabited scope if that scope is a block scope and
|
||
the target scope otherwise[.](#2.sentence-2)
|
||
|
||
An entity [*belongs*](#def:entity,belong "6.4.1 General [basic.scope.scope]") to a scope S if S is the target scope of a declaration of the entity[.](#2.sentence-3)
|
||
|
||
[*Note [1](#note-1)*:
|
||
|
||
Special cases include that:
|
||
|
||
- [(2.6)](#2.6)
|
||
|
||
Template parameter scopes are parents
|
||
only to other template parameter scopes ([[basic.scope.temp]](basic.scope.temp "6.4.9 Template parameter scope"))[.](#2.6.sentence-1)
|
||
|
||
- [(2.7)](#2.7)
|
||
|
||
Corresponding declarations with appropriate linkage
|
||
declare the same entity ([[basic.link]](basic.link "6.7 Program and linkage"))[.](#2.7.sentence-1)
|
||
|
||
- [(2.8)](#2.8)
|
||
|
||
The declaration in a [*template-declaration*](temp.pre#nt:template-declaration "13.1 Preamble [temp.pre]") inhabits the same scope as the [*template-declaration*](temp.pre#nt:template-declaration "13.1 Preamble [temp.pre]")[.](#2.8.sentence-1)
|
||
|
||
- [(2.9)](#2.9)
|
||
|
||
Friend declarations and
|
||
declarations of template specializations do not bind names ([[dcl.meaning]](dcl.meaning "9.3.4 Meaning of declarators"));
|
||
those with qualified names target a specified scope, and
|
||
other friend declarations and
|
||
certain [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]")*s* ([[dcl.type.elab]](dcl.type.elab "9.2.9.5 Elaborated type specifiers"))
|
||
target a larger enclosing scope[.](#2.9.sentence-1)
|
||
|
||
- [(2.10)](#2.10)
|
||
|
||
Block-scope extern or function declarations target a larger enclosing scope
|
||
but bind a name in their immediate scope ([[dcl.meaning.general]](dcl.meaning.general "9.3.4.1 General"))[.](#2.10.sentence-1)
|
||
|
||
- [(2.11)](#2.11)
|
||
|
||
The names of unscoped enumerators are bound
|
||
in the two innermost enclosing scopes ([[dcl.enum]](dcl.enum "9.8.1 Enumeration declarations"))[.](#2.11.sentence-1)
|
||
|
||
- [(2.12)](#2.12)
|
||
|
||
A class's name is also bound in its own scope ([[class.pre]](class.pre "11.1 Preamble"))[.](#2.12.sentence-1)
|
||
|
||
- [(2.13)](#2.13)
|
||
|
||
The names of the members of an anonymous union are bound in
|
||
the union's parent scope ([[class.union.anon]](class.union.anon "11.5.2 Anonymous unions"))[.](#2.13.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1013)
|
||
|
||
Two non-static member functions have[*corresponding object parameters*](#def:object_parameter,corresponding "6.4.1 General [basic.scope.scope]") if
|
||
|
||
- [(3.1)](#3.1)
|
||
|
||
exactly one is an implicit object member function
|
||
with no [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1 General [dcl.decl.general]") and
|
||
the types of their object parameters ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")),
|
||
after removing references,
|
||
are the same, or
|
||
|
||
- [(3.2)](#3.2)
|
||
|
||
their object parameters have the same type[.](#3.sentence-1)
|
||
|
||
Two non-static member function templates have[*corresponding object parameters*](#def:object_parameter,corresponding "6.4.1 General [basic.scope.scope]") if
|
||
|
||
- [(3.3)](#3.3)
|
||
|
||
exactly one is an implicit object member function
|
||
with no [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1 General [dcl.decl.general]") and
|
||
the types of their object parameters,
|
||
after removing any references,
|
||
are equivalent, or
|
||
|
||
- [(3.4)](#3.4)
|
||
|
||
the types of their object parameters are equivalent[.](#3.sentence-2)
|
||
|
||
Two function templates have[*corresponding signatures*](#def:signature,corresponding "6.4.1 General [basic.scope.scope]") if
|
||
their [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]")*s* have the same length,
|
||
their corresponding [*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]")*s* 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[.](#3.sentence-3)
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1048)
|
||
|
||
Two declarations [*correspond*](#def:correspond "6.4.1 General [basic.scope.scope]") if they (re)introduce the same name,
|
||
both declare constructors, or
|
||
both declare destructors,
|
||
unless
|
||
|
||
- [(4.1)](#4.1)
|
||
|
||
either is a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]"), or
|
||
|
||
- [(4.2)](#4.2)
|
||
|
||
one declares a type (not a type alias) and the other declares a
|
||
variable,
|
||
non-static data member other than of an anonymous union ([[class.union.anon]](class.union.anon "11.5.2 Anonymous unions")),
|
||
enumerator,
|
||
function, or
|
||
function template, or
|
||
|
||
- [(4.3)](#4.3)
|
||
|
||
each declares a function or function template
|
||
and they do not declare corresponding overloads[.](#4.sentence-1)
|
||
|
||
Two function or function template declarations declare[*corresponding overloads*](#def:corresponding_overloads "6.4.1 General [basic.scope.scope]") if
|
||
|
||
- [(4.4)](#4.4)
|
||
|
||
both declare functions with the same non-object-parameter-type-list,[17](#footnote-17 "An implicit object parameter ([over.match.funcs]) is not part of the parameter-type-list.") equivalent ([[temp.over.link]](temp.over.link "13.7.7.2 Function template overloading")) trailing [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]")*s* (if any, except as specified in [[temp.friend]](temp.friend "13.7.5 Friends")), and,
|
||
if both are non-static members,
|
||
they have corresponding object parameters, or
|
||
|
||
- [(4.5)](#4.5)
|
||
|
||
both declare function templates with corresponding signatures and equivalent[*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]")*s* and
|
||
trailing [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]")*s* (if any)[.](#4.sentence-2)
|
||
|
||
[*Note [2](#note-2)*:
|
||
|
||
Declarations can correspond even if neither binds a name[.](#4.sentence-3)
|
||
|
||
[*Example [1](#example-1)*: struct A {friend void f(); // #1};struct B {friend void f() {} // corresponds to, and defines, #1}; â *end example*]
|
||
|
||
â *end note*]
|
||
|
||
[*Example [2](#example-2)*: typedef int Int;enum E : int { a };void f(int); // #1void f(Int) {} // defines #1void f(E) {} // OK, another overloadstruct X {static void f(); void f() const; // error: redeclarationvoid g(); void g() const; // OKvoid g() &; // error: redeclarationvoid h(this X&, int); void h(int) &&; // OK, another overloadvoid j(this const X&); void j() const &; // error: redeclarationvoid k(); void k(this X&); // error: redeclaration}; â *end example*]
|
||
|
||
[5](#5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1124)
|
||
|
||
A declaration is [*name-independent*](#def:declaration,name-independent "6.4.1 General [basic.scope.scope]") if its name is _ (U+005f low line) and it declares
|
||
|
||
- [(5.1)](#5.1)
|
||
|
||
a variable with automatic storage duration,
|
||
|
||
- [(5.2)](#5.2)
|
||
|
||
a structured binding
|
||
with no [*storage-class-specifier*](dcl.stc#nt:storage-class-specifier "9.2.2 Storage class specifiers [dcl.stc]") and
|
||
not inhabiting a namespace scope,
|
||
|
||
- [(5.3)](#5.3)
|
||
|
||
a result binding ([[dcl.contract.res]](dcl.contract.res "9.4.2 Referring to the result object")),
|
||
|
||
- [(5.4)](#5.4)
|
||
|
||
the variable introduced by an [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]"), or
|
||
|
||
- [(5.5)](#5.5)
|
||
|
||
a non-static data member of other than an anonymous union[.](#5.sentence-1)
|
||
|
||
*Recommended practice*: Implementations should not emit a warning
|
||
that a name-independent declaration is used or unused[.](#5.sentence-2)
|
||
|
||
[6](#6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1150)
|
||
|
||
Two declarations [*potentially conflict*](#def:potentially_conflict "6.4.1 General [basic.scope.scope]") if they correspond and
|
||
cause their shared name to denote different entities ([[basic.link]](basic.link "6.7 Program and linkage"))[.](#6.sentence-1)
|
||
|
||
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]](basic.lookup "6.5 Name lookup")),
|
||
unless B is name-independent[.](#6.sentence-2)
|
||
|
||
[*Note [3](#note-3)*:
|
||
|
||
An [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") 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]](basic.lookup.general "6.5.1 General"))[.](#6.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[*Note [4](#note-4)*:
|
||
|
||
Overload resolution can consider potentially conflicting declarations
|
||
found in multiple scopes
|
||
(e.g., via [*using-directive*](namespace.udir#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]")*s* or for operator functions),
|
||
in which case it is often ambiguous[.](#6.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [3](#example-3)*: void f() {int x,y; void x(); // error: different entity for xint y; // error: redefinition}enum { f }; // error: different entity for ::fnamespace A {}namespace B = A;namespace B = A; // OK, no effectnamespace B = B; // OK, no effectnamespace A = B; // OK, no effectnamespace B {} // error: different entity for Bvoid g() {int _;
|
||
_ = 0; // OKint _; // OK, name-independent declaration _ = 0; // error: two non-function declarations in the lookup set}void h () {int _; // #1 _ ++; // OKstatic int _; // error: conflicts with #1 because static variables are not name-independent} â *end example*]
|
||
|
||
[7](#7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1199)
|
||
|
||
A declaration is [*nominable*](#def:nominable "6.4.1 General [basic.scope.scope]") 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]](namespace.def "9.9.2 Namespace definition"))[.](#7.sentence-1)
|
||
|
||
[*Example [4](#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[.](#7.sentence-2)
|
||
|
||
â *end example*]
|
||
|
||
[8](#8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1225)
|
||
|
||
When instantiating a templated entity ([[temp.pre]](temp.pre "13.1 Preamble")),
|
||
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[.](#8.sentence-1)
|
||
|
||
[17)](#footnote-17)[17)](#footnoteref-17)
|
||
|
||
An implicit object parameter ([[over.match.funcs]](over.match.funcs "12.2.2 Candidate functions and argument lists"))
|
||
is not part of the parameter-type-list[.](#footnote-17.sentence-1)
|