类中成员的范围

Scope of members in class

本文关键字:范围 成员      更新时间:2023-10-16

在下面的例子中,数组v的大小保证是2还是3?

static const int i = 3;
class X {
    char v[i];
    static const int i = 2;
};

从标准,

3.3.6/2在类S中使用的名称N应在其上下文中以及在S的完整范围内重新评估时引用相同的声明

我认为这意味着' I '应该是2,这里的重新评估是什么意思?

正确的行为应该是导致错误,因为重新求值会改变含义:

来自3.3.6节的例子:

扩展到类定义末尾或之后的声明的潜在作用域也扩展到其成员定义所定义的区域,即使成员是在类的外部词法定义的(包括静态数据成员定义、嵌套类定义、成员函数定义(包括成员函数体),对于构造函数(12.1),(ctor-initializer(12.6.2))和此类定义中紧跟标识符的声明符部分的任何部分,包括形参声明子句和任何默认实参(8.3.6)。(例子:

该示例与您的示例类似(使用enum而不是static const int):

typedef int  c;
enum { i = 1 };
class X {
    char  v[i];    // error: i refers to ::i
                   // but when reevaluated is X::i
    int  f() { return sizeof(c); } // OK X::c
    char  c;
    enum { i = 2 };
};

在遇到v[i]时,编译器只知道enum { i = 1 };(或static const int i = 3;),但当知道完整的类声明时,char v[i]将不同,因为i将被重新求值为2

在这种情况下数组的大小应该是3。如果你逐行查看你的代码。编译器在构造数组时对X::i一无所知。

当数组的大小变为2时,如果你改变类内的行,它将首先隐藏