Тест инициализации статических переменных

#include <stdio.h>

class C
{
   public:
          static int i;
          static int j;
};

int i = 10;
int C::i = 20;
int C::j = i + 1;

int main ()
{
    printf("%d", C::j);

    return 0;
}

Каково значение: C:: j

Я читал викторину С++ и наткнулся на следующий вопрос. Я думал, что ответ 11.

int C::j = i + 1;

Поскольку он обращается к нестационарной i, которая равна 10? Итак, я думал, что 11 должен быть ответом?

Я скомпилировал и запустил этот код через визуальную студию, и он печатает 21. Что меня смущает. Может кто-нибудь объяснить, почему это происходит? Что мне не хватает?

Ответы

Ответ 1

[basic.lookup.qual]/3

В объявлении, в котором идентификатор-идентификатор является квалифицированным идентификатором, имена, используемые перед объявлением квалифицированного идентификатора просматриваются в области определения пространства имен; имена, следующие за квалифицированным идентификатором, просматриваются в области класса участников или пространства имен.

В

int C::j = i + 1;

идентификатор объявления, т.е. имя объявляемого объекта, C::j, который является идентификатором-квалифицированным. Поэтому i после него просматривается в области C и относится к C::i.

Менее технически, когда вы определяете статический член данных, инициализатор можно рассматривать как находящийся в сфере действия класса, и будет находить члены класса перед глобальными.

Это то же самое правило, которое гарантирует, что, когда функция-член определена вне строки, имена после имени функции будут искать в области класса и не будут требовать явной квалификации, если они относятся к членам класса, Более необычно видеть, что это применяется к определениям статических элементов данных, но оно абсолютно согласовано.