int x = 42;
struct A {
static int x; // 1
};
int A::x = x; // 2
Почему в 2 повторное объявление x
находится в области класса? Где находится локус какого-то объявления — только при первом объявлении (1) или каждое переобъявление имеет свой локус (1 и 2)?
Не уверен, что вы спрашиваете. Когда вы находитесь в глобальной области видимости, x
— глобальный, а A::x
— статический класс.
@wohlstad Нет, второй x
в int A::x = x;
на самом деле статический.
Не могли бы вы привести цитату, объясняющую, почему A::x
находится в области класса, а не в глобальной области?
В // 2
вы снова входите в область действия класса в той точке, где появляется A::
. Отсюда, вплоть до ;
в конце определения, вы можете использовать любое имя, объявленное в классе.
@user12002570 user12002570 Понятно. Это потому, что упоминание A::x
выводит нас в область действия класса?
@wohlstad По сути, при поиске в дополнение к глобальной области поиска также используется указанный класс (который здесь A
). Это из-за A::x
@tbxfreeware, не могли бы вы предоставить ссылку на цитату, объясняющую это?
@wohlstad Это (A::x
) очень актуально.
@user12002570 user12002570 Хорошо, тогда это имеет больше смысла.
Это не ответ на вопрос, но вы можете уточнить область действия, используя = ::x;
.
@BoP смысл неполного имени состоит в том, чтобы показать, что A::x
на самом деле находится в области класса, т. е. имя x
позже относится к статическому члену, а не к глобальной переменной.
Вы неправильно поняли @BoP.
Я не могу воспроизвести, godbolt.org/z/daaGqnT1E, какой компилятор и настройки вы используете?
См. этот ответ в дюпе: Поиск имени и область действия класса
Почему в 2 повторное объявление x
находится в области класса? Это так?
@Language Lawyer Внутри класса глобальный x
скрыт статическим x
. Вы можете получить доступ к глобальному x
, но только если у вас есть к нему доступ: ::x
. Во внешнем определении A::x
вы повторно входите в область действия класса, которая затем расширяется до ;
, что завершает определение. В этой области глобальный x
снова скрыт. Чтобы добраться до него, вы должны его охватить. В противном случае любое появление x
относится к статической переменной, определенной в классе.
@tbxfreeware это не требует присутствия в области класса
Конечно. Приоритет поиска имени такой же, как если бы вы повторно вошли в область действия класса. Если, например, существуют базовые классы или A
является вложенным классом, эти классы будут проверены перед рассмотрением лексической области внешнего определения. Я всегда думал об этом как о «повторном входе» в рамки класса, но если это неправильный термин, я поправлюсь.
@cppbest вновь открыт.
@LanguageLawyer, вы имеете в виду, что «находиться в области видимости» — это не то же самое, что «присутствовать в области видимости»?
Целевая область A::x
— это область класса A
, потому что [dcl.meaning.general]/(3.4):
В противном случае имя терминала идентификатора-декларатора не ищется. Если это квалифицированное имя, декларатор должен соответствовать одному или нескольким объявлениям, номинируемым в S; все объявления должны иметь одну и ту же целевую область, и целевая область декларатора — это эта область.
(Здесь S — контекст поиска A::x
[dcl.meaning.general]/(3.1).)
Этот ответ не объясняет, почему эти два слова разные, хотя они кажутся одинаковыми: int A::x = x;
и int A::x = ::x;
.
@ChukwujiobiCanon eel.is/c++draft/basic.scope.class#1.sentence-2
Все еще не отвечает на мой комментарий.
@ChukwujiobiCanon это не вопрос ОП.
@ChukwujiobiCanon • A::x
и x
относятся к x
в области A
. ::x
относится к x
в глобальной области, а не к A
. Вот почему они не одинаковы.
@Элджей, я знаю это. Прочтите ответ еще раз. Ответ касается другой темы. В ответе должна была быть ссылка на другую часть стандарта, а не на эту. В любом случае я остаюсь в стороне.
Это ответ, спасибо.
«Почему в 2 повторное объявление x находится в области класса?...» Потому что вы написали
A::x
, означающее, что любое имя после этого также будет искаться в области класса.