Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Scope

      From cppreference.com
      <cpp‎ |language
       
       
      C++ language
      General topics
      Flow control
      Conditional execution statements
      Iteration statements (loops)
      Jump statements
      Functions
      Function declaration
      Lambda function expression
      inline specifier
      Dynamic exception specifications(until C++17*)
      noexcept specifier(C++11)
      Exceptions
      Namespaces
      Types
      Specifiers
      constexpr(C++11)
      consteval(C++20)
      constinit(C++20)
      Storage duration specifiers
      Initialization
      Expressions
      Alternative representations
      Literals
      Boolean -Integer -Floating-point
      Character -String -nullptr(C++11)
      User-defined(C++11)
      Utilities
      Attributes(C++11)
      Types
      typedef declaration
      Type alias declaration(C++11)
      Casts
      Memory allocation
      Classes
      Class-specific function properties
      Special member functions
      Templates
      Miscellaneous
       
       

      Eachdeclaration that appears in a C++ program is only visible in some possibly discontiguousscopes .

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

      Contents

      [edit]General

      Each program has aglobal scope , whichcontains the entire program.

      Every other scopeS is introduced by one of the following:

      (since C++26)

      S always appear in another scope, which therebycontainsS.

      Anenclosing scope at a program point is any scope that contains it; the smallest such scope is said to be theimmediate scope at that point.

      A scopeintervenes between a program pointP and a scopeS (that does not containP) if it is or containsS but does not containP.

      Theparent scope of any scopeS that is not atemplate parameter scope is the smallest scope that containsS and is not a template parameter scope.

      Unless otherwise specified:

      • A declarationinhabits the immediate scope at itslocus.
      • A declaration’starget scope is the scope it inhabits.
      • Any names (re)introduced by a declaration arebound to it in its target scope.

      An entitybelongs to a scopeS ifS is the target scope of a declaration of the entity.

      //                global  scope  scope//                scope     S      Tint x;//   ─┐                 // program point X//    │{//    │     ─┐{//    │      │     ─┐int y;//    │      │      │   // program point Y}//    │      │     ─┘}//   ─┘     ─┘

      In the program above:

      • The global scope, scopeS and scopeT contains program pointY.
      • In other words, these three scopes are all enclosing scopes at program pointY.
      • The global scope contains scopesS andT, and scopeS contains scopeT.
      • Therefore, scopeT is the smallest scope among all three, which means:
      • ScopeT is the immediate scope at program pointY.
      • The declaration of the variabley inhabits scopeT at its locus.
      • ScopeT is the target scope of the declaration ofy.
      • The variabley belongs to scopeT.
      • ScopeS is the parent scope of scopeT, and the global scope is the parent scope of scopeS.
      • ScopeS intervenes between program pointX and scopeT.

      [edit]Block scope

      Each

      introduces ablock scope that includes the statement or handler.

      A variable that belongs to a block scope is ablock variable  (also known as local variable).

      int i=42;int a[10]; for(int i=0; i<10; i++)// inner “i” inhabits the block scope    a[i]= i;// introduced by the for-statement int j= i;// j = 42

      If the declaration inhabits a block scopeS and declares a function or uses theextern specifier, the declaration shall not be attached to anamed module (since C++20), its target scope is a larger enclosing scope (the innermost enclosing namespace scope), but the name is bound in their immediate scopeS.

      If a declaration that is not aname-independent declaration and(since C++26) that binds a name in the block scopeS of

      (since C++11)
      • a substatement of a selection or iteration statement that is not itself a selection or iteration statement, or
      • a handler of a functiontry block

      potentially conflicts with a declaration whose target scope is the parent scope ofS, the program is ill-formed.

      if(int x= f())// declares “x”{// the if-block is a substatement of the if-statementint x;// error: redeclaration of “x”}else{// the else-block is also a substatement of the if-statementint x;// error: redeclaration of “x”} void g(int i){externint i;// error: redeclaration of “i”}

      [edit]Function parameter scope

      Eachparameter declarationP introduces afunction parameter scope that includesP.

      • If the function declaration is afunction definition, the scope introduced is extended to the end of the function definition.
      • Otherwise (the function declaration is a function prototype), the scope introduced is extended to the end of the function declarator.
      • In both cases, the scope does not include thelocus of the function declaration.
      • If the declared parameter is of the parameter list of alambda expression, the scope introduced is extended to the end of{body}.
      (since C++11)
      • If the declared parameter is of the parameter list of adeduction guide, the scope introduced is extended to the end of that deduction guide.
      (since C++17)
      • If the declared parameter is of the parameter list of arequires expression, the scope introduced is extended to the end of{requirement-seq}.
      (since C++20)
      int f(int n)// the declaration of the parameter “n”{// introduces a function parameter scope/* ... */}// the function parameter scope ends here

      Lambda scope

      Eachlambda expression introduces alambda scope that starts immediately after[captures ] and extends to the end of{body}.

      Thecaptures with initializers of a lambda expressionE inhabit the lambda scope introduced byE.

      auto lambda=[x=1, y]()// this lambda expression introduces a lambda scope,{// it is the target scope of capture “x”/* ... */};// the lambda scope ends before the semicolon
      (since C++14)

      [edit]Namespace scope

      Everynamespace definition for a namespaceN introduces anamespace scopeS that includes thedeclarations for every namespace definition forN.

      For each non-friend redeclaration or specialization whose target scope isS or is contained byS, the following portions are also included in scopeS:

      • For aclass (template) redeclaration or class template specialization, the portion after itsclass-head-name.
      • For aenumeration redeclaration, the portion after itsenum-head-name.
      • For any other redeclaration or specialization, the portion after theunqualified-id orqualified-id of thedeclarator.

      Theglobal scope is the namespace scope of theglobal namespace.

      namespace V// the namespace definition of “V”{// introduces a namespace scope “S”// the first part of scope “S” begins herevoid f();// the first part of scope “S” ends here} void V::f()// the portion after “f” is also a part of scope “S”{void h();// declares V::h}// the second part of scope “S” ends here

      [edit]Class scope

      Each declaration of a class or class templateC introduces aclass scopeS that includes themember-specification of theclass definition ofC.

      For each non-friend redeclaration or specialization whose target scope isS or is contained byS, the following portions are also included in scopeS:

      • For aclass (template) redeclaration or class template specialization, the portion after itsclass-head-name.
      • For aenumeration redeclaration, the portion after itsenum-head-name.
      • For any other redeclaration or specialization, the portion after theunqualified-id orqualified-id of thedeclarator.
      class C// the class definition of “C”{// introduces a class scope “S”// the first part of scope “S” begins herevoid f();// the first part of scope “S” ends here} void C::f()// the portion after “f” is also a part of scope “S”{/* ... */}// the second part of scope “S” ends here

      [edit]Enumeration scope

      Each declaration of an enumerationE introduces anenumeration scope that includes theenumerator-list of the non-opaque(since C++11)enumeration declaration ofE (if present).

      enumclass E// the enumeration declaration of “E”{// introduces an enumeration scope “S”// scope “S” begins here    e1, e2, e3// scope “S” ends here}

      [edit]Template parameter scope

      Eachtemplate template parameter introduces atemplate parameter scope that includes the entire template parameter list and therequire clauses(since C++20) of that template template parameter.

      Each template declarationD introduces atemplate parameter scopeS that extends from the beginning of the template parameter list ofD to the end ofD. Any declaration outside the template parameter list that would inhabitS instead inhabits the same scope asD.

      Only template parameters belong to a template parameter scope, and only template parameter scopes have a template parameter scope as a parent scope.

      // the class template declaration of “X”// introduces a template parameter scope “S1”template<// scope “S1” begins heretemplate// the template template parameter “T”// introduces another template parameter scope “S2”<typename T1typename T2> requires std::convertible_from<T1, T2>// scope “S2” ends hereclass T,typename U>class X;// scope “S1” ends before the semicolon namespace N{template<typename T>using A=struct X;// “X” inhabits the same scope as template// declaration, namely the scope of “N”}

      Contract-assertion scope

      Eachcontract assertionC introduces acontract-assertion scope thatincludesC.

      If apostcondition assertion has anidentifier which is notname-independent, and the postcondition assertion is associated with a functionfuncpotentially conflicts with a declarationD whose target scope is one of the following scopes, the program is ill-formed:

      • The function parameter scope offunc.
      • IfD is associated with alambda expression, the nearest enclosing lambda scope of the precondition assertion.
      (since C++26)

      [edit]Point of declaration

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

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

      int x=32;// outer x is in scope {int x= x;// inner x is in scope before the initializer (= x)// this does not initialize inner x with the value of outer x (32),// this initializes inner x with its own (indeterminate) value} std::function<int(int)> f=[&](int n){return n>1? n* f(n-1): n;};// the name of the function f is in scope in the lambda and can// be correctly captured by reference, giving a recursive function
      constint x=2;// outer x is in scope {int x[x]={};// inner x is in scope before the initializer (= {}),// but after the declarator (x[x])// in the declarator, outer x is still in scope// this declares an array of 2 int}

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

      struct S:std::enable_shared_from_this<S>{};// S is in scope at the colon

      The locus ofenum specifier or opaque enum declaration(since C++11) is immediately after the identifier that names the enumeration.

      enum E:int// E is in scope at the colon{    A= sizeof(E)};

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

      using T=int;// outer T is in scope at the semicolon {using T= T*;// inner T is in scope at the semicolon,// outer T is still in scope before the semicolon// same as T = int*}

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

      template<int N>class Base{protected:staticconstint next= N+1;staticconstint value= N;}; struct Derived: Base<0>, Base<1>, Base<2>{using Base<0>::next,// next is in scope at the comma          Base<next>::value;// Derived::value is 1};

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

      constint x=12; {enum{        x= x+1,// enumerator x is in scope at the comma,// outer x is in scope before the comma,// enumerator x is initialized to 13        y= x+1// y is initialized to 14};}

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

      template<typename T>struct Array//  : std::enable_shared_from_this<Array> // error: the injected class name is not in scope:std::enable_shared_from_this< Array<T>>// OK: the template-name Array is in scope{// the injected class name Array is now in scope as if a public member name    Array* p;// pointer to Array<T>};

      The locus of the implicit declaration for a function-local predefined variable__func__ is immediately before the function body of a function definition.

      (since C++11)


      The locus of astructured binding declaration is immediately after theidentifier-list, but structured binding initializers are prohibited from referring to any of the names being declared.

      (since C++17)


      The locus of the variable or the structured bindings(since C++17) declared in therange-declaration of arange-for loop is immediately after therange-expression.

      std::vector<int> x; for(auto x: x)// vector x is in scope before the closing parenthesis,// auto x is in scope at the closing parenthesis{// the auto x is in scope}
      (since C++11)

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

      typedefunsignedchar T; template<class T= T,// template parameter T is in scope at the comma,// typedef name of unsigned char is in scope before the comma    T// template parameter T is in scope    N=0>struct A{};

      The locus of apostcondition assertion with anidentifier is immediately after its:.

      (since C++26)


      The locus of aconcept definition is immediately after the concept name, but concept definitions are prohibited from referring to the concept name being declared.

      (since C++20)

      The locus of a namednamespace definition is immediately after the namespace name.

      This section is incomplete
      Reason: remainder of [basic.scope.pdecl]

      [edit]Defect reports

      The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

      DRApplied toBehavior as publishedCorrect behavior
      CWG 2793C++98anextern declaration in a block scope could
      conflict with another declaration in the parent scope
      prohibited

      [edit]References

      • C++23 standard (ISO/IEC 14882:2024):
      • 6.4 Scope [basic.scope]
      • C++20 standard (ISO/IEC 14882:2020):
      • 6.4 Scope [basic.scope]
      • C++17 standard (ISO/IEC 14882:2017):
      • 6.3 Scope [basic.scope]
      • C++14 standard (ISO/IEC 14882:2014):
      • 3.3 Scope [basic.scope]
      • C++11 standard (ISO/IEC 14882:2011):
      • 3.3 Scope [basic.scope]
      • C++98 standard (ISO/IEC 14882:1998):
      • 3.3 Declarative regions and scopes [basic.scope]

      [edit]See also

      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/scope&oldid=183347"

      [8]ページ先頭

      ©2009-2025 Movatter.jp