C++ - Создание типа конкретного размера

252
28 августа 2021, 13:10

У меня есть необходимость хранить значение цвета в формате 0xAARRGGBB, то есть, нужен тип, занимающий 4 байта. Я использую unsigned int, но, насколько знаю, на 32-разрядном процессоре, uint, в зависимости от компилятора, может весить 2 байта. Возникает вопрос, как бы объявить тип ARGB, чтобы он занимал 4 байта, через typedef? Можно ли как-нибудь, например, через условную компиляцию, сделать typedef от unsigned, если sizeof(unsigned) == 4 и от unsigned long иначе? Я не хочу создавать класс, содержащий 4 char'а, мне нужно, чтобы он был числовым, в т.ч. чтобы работал вариант

ARGB color = 0xff000000;  

На данный момент у меня просто typedef unsigned int ARGB;

P.S.
Qt использует такой же
typedef unsigned int QRgb;
Однако, как я понимаю, qmake использует компилятор, в котором int всегда весит 4 байта

Answer 1

Смотрим в сstdint и выбираем тип uint32_t...

Если очень хочется выкрутиться через sizeof, то можно поиграться в шаблонные игры типа

template<size_t N>
struct uint
{
    using type = 
        conditional_t<sizeof(unsigned char) == N, unsigned char,
        conditional_t<sizeof(unsigned short int) == N, unsigned short int,
        conditional_t<sizeof(unsigned int) == N, unsigned int,
        conditional_t<sizeof(unsigned long) == N, unsigned long,
        conditional_t<sizeof(unsigned long long) == N, unsigned long long,
        void>>>>>;
    static_assert(!is_same_v<type,void>,"Error - type not exist");
};
using  u4int = uint<4>::type;
Answer 2

Стандартная библиотеки языков С и С++ не гарантируют наличия типов конкретного размера, т.е. наличия типов вроде std::uint32_t не гарантируется - это опциональные типы. Если вы хотите портабельности/платформеннонезависимости вашего кода на уровне языка, то либо используйте тип минимально достаточного размера, вроде std::uint_least32_t, либо конструируйте некий свой агрегатный тип самостоятельно. Если вам нужна бинарная междуплатформенная портабельность, то остается лишь последний вариант.

Answer 3

Если Вы действительно не знаете для какой системы и каким компилятором будет транслироваться программа то стоит учесть, что есть системы как little-endian так и big-endian. Именно поэтому стоит использовать четыре байта. А если быть точнее то именно четыре uint8_t. Таким образом порядок байт и их разрядность будет соблюдена. Для удобства можно создать класс, который будет приводить данную структуру к unsigned int путем побитового сдвига, что также будет гарантировать правильное расположение значений цвета во всех системах.

Answer 4

Я не хочу создавать класс, содержащий 4 char'а, мне нужно, чтобы он был числовым, в т.ч. чтобы работал вариант

ARGB color = 0xff000000;

Если уж Вы работаете в С++, то как раз нужно создать класс, содержащий 4 char'а. А потом перегрузить присваивание константой для этого класса, чтобы работало ARGB color = 0xff000000;

Это и будет С++-way. :-)

READ ALSO
ошибка, связанная с gets() c++

ошибка, связанная с gets() c++

решаю задачу на coderbyte, там массив читается так:

94
Выход из масива | Помогите пожалуйста

Выход из масива | Помогите пожалуйста

ПриветТакая проблема, что после строчки int coc=0; Цикл с вложенным, там xPtr выходит за рамки, не понимаю почему, можете помочь пожалуйста решить...

112
Не выполняется сложение с float

Не выполняется сложение с float

Я выполняю сложение float + floatМне надо в цикле прибавить к массиву типа float значение переменной Eps=0

102
Помогите разобраться с интерфейсом

Помогите разобраться с интерфейсом

При попытке скомпилировать проект возникает ошибка

112