Что происходит, когда происходит Injected-Class-Name? (C ++) - PullRequest
4 голосов
/ 28 января 2020

В соответствии с https://en.cppreference.com/w/cpp/language/injected-class-name

В области видимости имя текущего класса обрабатывается так, как если бы оно было публичным c именем члена; это называется injected-class-name. Точка объявления имени следует сразу за открывающей скобкой определения класса.

int X;
struct X {
    void f() {
        X* p; // OK. X refers to the injected-class-name
        ::X* q; // Error: name lookup finds a variable name, which hides the struct name
    }
};

Так что же на самом деле происходит в коде? X* p превратился в X::X* p?

Ответы [ 2 ]

6 голосов
/ 28 января 2020

Так что же на самом деле происходит в коде? X * p превращается в X::X* p?

В основном. Правила поиска имени начинаются в самой узкой области. Когда вы делаете X* p; в f, он смотрит в область действия f и ничего не находит. Затем он проверяет область действия X, поскольку f ограничен X. Он находит X, поскольку он внедряется в область видимости класса, поэтому останавливается там, и вы получаете тип класса.

Когда вы делаете ::X* q;, тогда ::X говорит, что ищет X в глобальном пространстве имен и там находит переменную, а не тип, поэтому вы получаете ошибку.

4 голосов
/ 28 января 2020

Это полное имя ::X ищется в глобальном пространстве имен. Поскольку не существует типа с таким именем (объявление переменной скрывает тип struct X), компилятор выдает ошибку.

Вы можете использовать сложное имя, например

int X;
struct X {
    void f() {
        X* p; // OK. X refers to the injected-class-name
        struct ::X* q; // OK. elaborated name struct ::X
    }
};
...