Сообщение Re[11]: так компайл тайм рефлекшину быть 26-й стандарт ?? от 25.03.2026 7:35
Изменено 25.03.2026 7:39 ботаныч
R>Здравствуйте, ботаныч, Вы писали:
Б>>Здравствуйте, rg45, Вы писали:
Б>>привет.
R>Хорошо, "то же самое" зачёркриваем. Оставляем только: "через оператор доступа к членам (точку) можно доступаться не только к инстансным, но и к статическим членам". Это было главной мыслью, которую я высказал для полноты картины использования этих двух операторов.
Да я вообще хотел обойти пока сторой вопрос со статикой отмазавшись фразой
Чего аж вообще не скажешь за оператор точка, который без инстанса (за некоторыми исключениями) рантайма неупотребим.
Б>>более близко выглядело бы ((std::numeric_limits<double>*)nullptr)->epsilon(), для статики.
R>Во-первых, это уже другой оператор (->), о котором и речи не шло изначально.
ближе, т.е. без создания инстанса (объекта)
R>Во-вторых, здесь тоже будет создан "инстанс", т.к. указатель — это тоже объект (нулевой указатель в т.ч).
разыменования здесь нет. здесь приведение nullptr к типу, в котором реализован статический метод.
R>Выигрыш по сравнению с созданием объекта пустой структуры сомнителен. В-третьих, я вот думаю, а не будет ли здесь UB (разыменовывание нулевого указателя)? Вот это не очень очевидно для меня — с одной стороны, разыменовывание налицо, с другой — доступа к области памяти, занимаемой объектом нет, this не используется даже формально.
собственно
для перехода в точку можно было бы написать (*(std::numeric_limits<double>*)nullptr).epsilon(), но тут уже UB, потому я написал самое близкое и корректное к std::numeric_limits<double>::epsilon().В выражении ((std::numeric_limits<double>*)nullptr)->epsilon() никакой объект не будет инстанцирован.
Это происходит по следующим причинам:
Статическая природа: Функция epsilon() определена как static constexpr. В языке C++ вызов статического метода через указатель — это лишь синтаксический способ указать компилятору на конкретный тип. Разыменования указателя в реальности не происходит.
Работа компилятора: Для вызова этой функции компилятору достаточно знать тип (std::numeric_limits). Он подставляет значение константы прямо в место вызова еще на этапе компиляции.
Отсутствие UB: Так как фактического обращения к памяти по адресу nullptr не случается, это выражение безопасно и не вызывает неопределенного поведения.
Но самое забавное, что мы даже не это обсуждаем, мы обсуждаем совсем другую точку, которую предложил коллега B0FEE664.
А именно точка времени компиляции со некими скрытыми итерабильными свойствами времени компиляции. А это немного другой оператор.
R>Здравствуйте, ботаныч, Вы писали:
Б>>Здравствуйте, rg45, Вы писали:
Б>>привет.
R>Хорошо, "то же самое" зачёркриваем. Оставляем только: "через оператор доступа к членам (точку) можно доступаться не только к инстансным, но и к статическим членам". Это было главной мыслью, которую я высказал для полноты картины использования этих двух операторов.
Да я вообще хотел обойти пока стороной вопрос со статикой отмазавшись фразой
в некоторые исключение как раз входила статика, constexpr, constval выражения в контексте decltype или sizeof(obj.field)Чего аж вообще не скажешь за оператор точка, который без инстанса (за некоторыми исключениями) рантайма неупотребим.
Б>>более близко выглядело бы ((std::numeric_limits<double>*)nullptr)->epsilon(), для статики.
R>Во-первых, это уже другой оператор (->), о котором и речи не шло изначально.
ближе, т.е. без создания инстанса (объекта)
R>Во-вторых, здесь тоже будет создан "инстанс", т.к. указатель — это тоже объект (нулевой указатель в т.ч).
разыменования здесь нет. здесь приведение nullptr к типу, в котором реализован статический метод.
R>Выигрыш по сравнению с созданием объекта пустой структуры сомнителен. В-третьих, я вот думаю, а не будет ли здесь UB (разыменовывание нулевого указателя)? Вот это не очень очевидно для меня — с одной стороны, разыменовывание налицо, с другой — доступа к области памяти, занимаемой объектом нет, this не используется даже формально.
собственно
для перехода в точку можно было бы написать (*(std::numeric_limits<double>*)nullptr).epsilon(), но тут уже UB, потому я написал самое близкое и корректное к std::numeric_limits<double>::epsilon().В выражении ((std::numeric_limits<double>*)nullptr)->epsilon() никакой объект не будет инстанцирован.
Это происходит по следующим причинам:
Статическая природа: Функция epsilon() определена как static constexpr. В языке C++ вызов статического метода через указатель — это лишь синтаксический способ указать компилятору на конкретный тип. Разыменования указателя в реальности не происходит.
Работа компилятора: Для вызова этой функции компилятору достаточно знать тип (std::numeric_limits). Он подставляет значение константы прямо в место вызова еще на этапе компиляции.
Отсутствие UB: Так как фактического обращения к памяти по адресу nullptr не случается, это выражение безопасно и не вызывает неопределенного поведения.
Но самое забавное, что мы даже не это обсуждаем, мы обсуждаем совсем другую точку, которую предложил коллега B0FEE664.
А именно точка времени компиляции со некими скрытыми итерабильными свойствами времени компиляции. А это немного другой оператор.