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, означающее, что любое имя после этого также будет искаться в области класса.