Заменить приведение в стиле c (long &) в C++

В исходном коде я получил приведение в стиле c:

unsigned long test = 0;
long & truc = (long&)test;

Предполагаю, что &truc берут адрес теста с типом long.

Как я могу сделать это на C++?

Спасибо!

Используйте std :: addressof

rak007 16.05.2018 14:30
(long &)test получает ссылку на long, которая относится к test.. Он не вычисляет адрес. Хотя он использует синтаксис «приведения», подобный C, это не приведение в стиле c, поскольку C не поддерживает ссылочные типы. В C ваш код не компилируется.
Peter 16.05.2018 14:31
reinterpret_cast<long&>(test);
Jarod42 16.05.2018 14:33

@ rak007 нет адреса в коде OP, их предположение неверно

463035818_is_not_a_number 16.05.2018 14:34

@Peter - это недопустимое приведение в C, но это является "приведение в стиле c". Этот термин относится к синтаксису и отличает этот код от четырех приведений в стиле C++ (static_cast, const_cast, dynamic_cast и reinterpret_cast).

Pete Becker 16.05.2018 14:35

@PeteBecker - достаточно честно. Хотя кажется немного странным обозначить конструкцию, которая была бы диагностирована как ошибка любым компилятором C, как «c-style».

Peter 16.05.2018 14:40

@Peter не более чем class myClass{ void foo(); }; myClass myArray[10] - это массив в стиле C только типа C++, чтобы отличить его от std::array<myClass, 10> myArray

Caleth 16.05.2018 14:43

@Caleth - разница в том, что можно представить себе объявление типа myClass myArray[10] действительным в C (например, если myClass является typedef для типа, который может быть указан в C). Довольно сложно представить себе способ, которым конструкция long &truc = (long &)test может быть действительной C. В любом случае, я хочу сказать, что OP задал вопрос таким образом, чтобы предположить, что это был код C, который необходимо было повторно выразить на C++ ( а также предположил, что он вычисляет адрес, но это не так), хотя на самом деле он вообще недействителен C.

Peter 16.05.2018 15:33
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
8
454
1

Ответы 1

Что вы имеете в виду, говоря «как [я могу] сделать это в C++»? Вы уже это сделали! Оно работает!

Если отвлечься от потенциально сомнительного псевдонима, приведение к ссылочному типу совершенно корректно и делает то, что вы ожидаете.

В более общем смысле такое приведение может использоваться для преобразования выражения в выражение с типом его основы, без копирование объекта, который он описывает:

Derived d;
Base& b = (Base&)d;

Хотя, чтобы быть идиоматичным, в таком случае вы бы предпочли static_cast:

Derived d;
Base& b = static_cast<Base&>(d);

В самом деле, способ преобразования C-стиля в C++ заключается в том, что в данном конкретном случае (приведение к ссылке на связанный тип) приведение C-стиля приводит к преобразованию является в static_cast.

Это также общий шаблон с dynamic_cast, который работает с типом указателя:

assert(dynamic_cast<T*>(ptr) != nullptr);

но также ссылочный тип:

try {
   dynamic_cast<T&>(*ptr);
}
catch (const std::bad_cast&) {}

Короче говоря, в приведении к ссылочному типу нет ничего плохого или странного.

При этом я бы избегал сомнительных преобразований, таких как unsigned long в long - возможно, что этот псевдоним технически четко определен, но мне придется погрузиться в стандарт, чтобы быть уверенным, и это, на мой взгляд, является достаточной причиной, чтобы его избежать.

Одним из преимуществ перехода на static_cast является то, что, если преобразование разрешено нет, вы будете проинформированы. Затем вы можете по очереди переключиться на reinterpret_cast и продолжить свой сомнительный псевдоним. ;)


Дополнение

Aliasing between long and unsigned long is allowed ([basic.lval] 10), as long as the value is in range for both. But yeah, best avoided. – Sneftel

Если значение не слишком велико для long или для unsigned long, если вы используете unsigned long

Lightness Races in Orbit 16.05.2018 16:32

Другие вопросы по теме