В исходном коде я получил приведение в стиле c:
unsigned long test = 0;
long & truc = (long&)test;
Предполагаю, что &truc берут адрес теста с типом long.
Как я могу сделать это на C++?
Спасибо!
(long &)test получает ссылку на long, которая относится к test.. Он не вычисляет адрес. Хотя он использует синтаксис «приведения», подобный C, это не приведение в стиле c, поскольку C не поддерживает ссылочные типы. В C ваш код не компилируется.
reinterpret_cast<long&>(test);@ rak007 нет адреса в коде OP, их предположение неверно
@Peter - это недопустимое приведение в C, но это является "приведение в стиле c". Этот термин относится к синтаксису и отличает этот код от четырех приведений в стиле C++ (static_cast, const_cast, dynamic_cast и reinterpret_cast).
@PeteBecker - достаточно честно. Хотя кажется немного странным обозначить конструкцию, которая была бы диагностирована как ошибка любым компилятором C, как «c-style».
@Peter не более чем class myClass{ void foo(); }; myClass myArray[10] - это массив в стиле C только типа C++, чтобы отличить его от std::array<myClass, 10> myArray
@Caleth - разница в том, что можно представить себе объявление типа myClass myArray[10] действительным в C (например, если myClass является typedef для типа, который может быть указан в C). Довольно сложно представить себе способ, которым конструкция long &truc = (long &)test может быть действительной C. В любом случае, я хочу сказать, что OP задал вопрос таким образом, чтобы предположить, что это был код C, который необходимо было повторно выразить на C++ ( а также предположил, что он вычисляет адрес, но это не так), хотя на самом деле он вообще недействителен C.





Что вы имеете в виду, говоря «как [я могу] сделать это в 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
longandunsigned longis allowed ([basic.lval] 10), as long as the value is in range for both. But yeah, best avoided. – Sneftel
Если значение не слишком велико для long или для unsigned long, если вы используете unsigned long
Используйте std :: addressof