Область действия членов в классе

#c #class

#c #класс

Вопрос:

В следующем примере будет v ли гарантирован размер массива 2 или 3?

 static const int i = 3;

class X {

    char v[i];
    static const int i = 2;
};
 

Из стандартного,

3.3.6 /2 Имя N, используемое в классе S, должно ссылаться на то же объявление в его контексте и при повторной оценке в заполненной области S

Я думаю, это означает, что «я» должен быть 2 , и что на самом деле означает здесь переоценка?

Ответ №1:

Правильное поведение заключается в том, что оно должно вызывать ошибку, поскольку повторная оценка изменит значение:

Пример из раздела 3.3.6:

Потенциальная область объявления, которая простирается до или после конца определения класса, также распространяется на области, определенные его определениями членов, даже если члены лексически определены вне класса (это включает определения членов со статическими данными, определения вложенных классов, определения функций-членов (включая тело функции-члена идля функций конструктора (12.1), ctor-инициализатора (12.6.2)) и любой части части декларатора таких определений, которая следует за идентификатором, включая параметр-объявление-предложение и любые аргументы по умолчанию (8.3.6). [Пример:

Пример похож на ваш (используется enum вместо a 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 .

Ответ №2:

В этом случае размер массива должен быть равен 3. Если вы посмотрите в свой код построчно. Составитель ничего не знает о X::i при создании массива. Если вы измените строки внутри класса, когда размер массива станет 2 и вторым, я скроюсь первым.