Есть ли законный способ конвертировать указатель без знака в указатель std :: byte?

Я использую STB библиотека для загрузки изображений в память. Конкретная функция, stbi_load, возвращает указатель на unsigned char, который является массивом.

Я испытываю желание использовать новый C ++ 17 API для необработанных данных, std::byte, который позволил бы мне быть более выразительным, и позволил бы мне псевдоним необработанных данных пиксель за пикселем или цвет за цветом, приведя его к другому типу данных (целые числа разного размера).

Теперь я попробовал это:

std::unique_ptr<std::byte[], stbi_deleter>(stbi_load(...));

Конечно, это не сработало из-за отсутствия неявного преобразования.

Тогда я попробовал это:

std::unique_ptr<std::byte[], stbi_deleter>(
static_cast<std::byte*>(stbi_load(...))
);

Опять же, это все еще не сработало. Я должен был решить использовать reinterpret_cast вместо. И заставил меня задаться вопросом, является ли это преобразование законным или нет. Могу ли я законно преобразовать unsigned char* в std::byte* в соответствии со строгим правилом алиасинга? И тогда я могу привести данные к другому типу данных, как std::uint32_t* и мутировать это? Это также нарушит правило наложения имен?

-1

Решение

Строгое правило псевдонимов никогда не запрещает какие-либо преобразования указателей. Речь идет о типе выражения, обращающегося к объекту.

std::byte может быть псевдонимом любого другого типа, это упомянуто на странице cppreference, на которую вы ссылаетесь, а также в строгом правиле псевдонимов в стандарте (C ++ 17 basic.lval / 8.8). Так что это нормально использовать reinterpret_cast<std::byte *> а затем читать или писать массив unsigned char,

Если вы используете выражение типа uint32_t читать или писать массив unsigned char, что будет нарушать строгое правило алиасинга.

5

Другие решения

Могу ли я на законных основаниях преобразовать беззнаковый char * в std :: byte * в соответствии со строгим правилом алиасинга?

Да, именно поэтому std::byte «наследует» от unsigned char, Но вы должны пройти reinterpret_cast<> так же, как вы должны при приведении произвольного типа к char* или же unsigned char*

И затем я могу привести данные к другому типу данных, например std :: uint32_t *, и изменить его.

Вы не можете ничего сделать с std::byte что вы не можете с char* или же unsigned char*,

Главное std::byte кажется полезным, чтобы иметь функции, которые могут иметь как строковые, так и необработанные перегрузки.

Кроме того, он избавляется от следующего раздражения:

char val = foo();
std::cout << (int)val << "\n";
4

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector