加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 范围单词组合中使用的名称的含义

发布时间:2020-12-16 07:09:07 所属栏目:百科 来源:网络整理
导读:我不明白使用的名字的意义….它是什么意思?例如(3.4.1 / 7): A name used in the definition of a class X outside of a member function body… 请考虑以下示例: class A { static const int a = 4; }int b = A::a; 在用于全局范围的嵌套名称说明符之后
我不明白使用的名字的意义….它是什么意思?例如(3.4.1 / 7):

A name used in the definition of a class X outside of a member
function body…

请考虑以下示例:

class A { static const int a = 4; }

int b = A::a;

在用于全局范围的嵌套名称说明符之后的名称或者它是否用于类范围?

命名空间模拟在7.3.1 / 6中非常清楚地定义:

The enclosing namespaces of a declaration are those namespaces in
which the declaration lexically appears,except for a redeclaration of
a namespace member outside its original namespace (e.g.,a definition
as specified in 7.3.1.2).

解决方法

免责声明:警告,语言答案.

什么是“范围”?

通常,我会说范围被理解为{}所包含的程序文本的一部分,而不是初始化括号. TC PLv4 p157“声明在范围内引入了一个名称”.

声明区域

在[basic.scope.declarative] / 1中,我们找到了声明区域的定义:

Every name is introduced in some portion of program text called a declarative region,which is the largest part of the program in which that name is valid,that is,in which that name may be used as an unqualified name to refer to the same entity.

我想我们可以看到“那是”之后的部分作为名称有效性的定义.

范围

[basic.scope.declarative] / 1继续定义范围:

In general,each particular name is valid only within some possibly discontiguous
portion of program text called its scope.

这只定义了名称的范围.在“在全局范围中使用”或“在类的范围中使用”的短语中,术语范围与特定名称无关.同样,[basic.scope.declarative] / 3

The names declared by a declaration are introduced into the scope in which the declaration occurs,except […].

这里,术语范围也用于第二个含义,与特定名称无关.

定义“范围”的第二个含义

诸如块语句,命名空间和类之类的几种语言特性引入了新的范围.例如. [stmt.block] / 1

A compound statement defines a block scope.

第二种含义的范围至少在三种不同的背景下使用:

>抬头看X的范围
>用于X的范围
>在X的范围内

在X的范围内查找

示例:3.4.3 / 1

If the nested-name-specifier of a qualified-id nominates a class,the name specified after the nested-name-specifier is looked up in the scope of the class,except for the cases listed below.

class X
{
    int m;
    void foo() { int n; }
};

decltype(X::m) v; // legal
decltype(X::n) w; // illegal

在此上下文中,类X的范围不扩展到任何嵌套范围,例如成员函数或嵌套类.

用于X的范围

示例:3.3.7 / 2

The name of a class member shall only be used as follows:

  • in the scope of its class (as described above) or a class derived from its class,
  • […]
class X
{
    int m;
    void foo()
    {
        decltype(m) n;
    }
    static int o;
};
int X::o = decltype(m)();

这里,类X的范围扩展到嵌套范围和程序的其他部分,例如类主体之外的成员定义.

请注意,静态数据成员,嵌套类和本地类的初始化程序被显式定义为在声明静态数据成员/类的任何位置.对于成员函数,我只能找到非规范性的注释,例如9.3 / 5

The member function f of class X is defined in global scope; the notation X::f specifies that the function f is a member of class X and in the scope of class X.

据我所知,这个“在成员函数的范围内”,嵌套/本地类表示那些新引入的作用域是嵌套作用域.

“在X的范围内使用”在标准中不常出现.有人可能会争辩说3.3.7 / 2应该扩展到嵌套范围,以使“在范围内使用”符合“在范围内查找”.

属于X的范围

示例:8.5 / 13

An initializer for a static member is in the scope of the member’s class.

class X
{
    static int m;
    static int n;
};

int n;
int o;

int X::m = n; // X::n
int X::n = o; // ::o

非限定名称的名称查找按照每个相应类别[basic.lookup.unqual] / 1中列出的顺序搜索范围(复数).对于两个静态数据成员的初始值设定项,首先搜索类X的范围,然后搜索任何基类,然后搜索封闭范围(此处:全局范围),[basic.lookup.unqual] / 7.

“在X的范围内”的含义在我看来,对于不合格的查找,搜索的范围是搜索X中使用的名称的范围,可能还有访问规则(静态数据成员的初始化程序可以访问私有成员)等等).如上所述,这有效地将成员函数的范围和在其封闭类的主体外部定义的嵌套类嵌套在该封闭类的范围内.

试图定义X的范围

不包括“在X范围内使用”的奇怪扩展.

3.3.3至3.3.9对各种名称范围进行分类.我们可以使用这些类别对程序中可以声明名称的部分进行分类:程序的一部分,其中可以声明具有块作用域的名称是块作用域.可以声明具有类作用域的名称的程序的一部分是类作用域.我们仍然需要区分同类的不同范围:

void foo()
{                   // begin scope A
    int a;          // 
    {               // begin scope B
        int b;      // 
        int c;      //
    }               // end scope B
    int d;          //
}                   // end scope A

标准调用A的外部范围B(在名称查找中).但是,范围B不是范围A的一部分.可能类似于“B在A的范围内,但在B内声明的名称不在A的范围内”.考虑:

class A
{
    int m;
    class B
    {
        int n;
    };
};

这里,名称查找“在类A的范围内”将找不到具有非限定查找的嵌套类B的成员.也相关:匿名工会.

我认为执行这种分离的最佳方法是查看可以引入范围的各个语言功能.例如,[stmt.block] / 1“复合语句定义块范围.”然后我们可以查看程序的任何部分X,找到引入尚未结束的范围的最接近的先前语言特性(*),获取程序的所有区域,其中新声明的名称在同一范围内(**) ),并将其称为X的封闭范围.

(*)尚未结束:对于一个块,块的结尾等(即,由语言特征指定)或者,尚未结束=其中一个名称可能已被声明仍然有效
(**)在同一范围内:从这个新声明开始,搜索引入尚未结束的范围的最接近的先前语言特征,应该找到该程序的相同部分

这似乎符合[basic.scope.declarative] / 4中使用的声明区域的定义:

Given a set of declarations in a single declarative region,each of which specifies the same unqualified name,they shall all refer to the same entity,or [… = be function overloads],or [… = various exceptions].

据我所知,这与[basic.scope.declarative] / 1中给出的定义相矛盾:

int main()
{
    int x;
    {
        int x;
    }
}

这里,我们有两个声明指定相同的非限定名称.外部x作为名称也在内部{}内部有效;然而,这是一个完全合法的C程序.我怀疑声明区域实际上不应该与单个名称相关联.

我认为可以通过使用终端{和}来简化范围的这个定义.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读