Как получить наименьший тип, который будет хранить массив чисел, не превышающих заданное значение n? Текущее решение, которое я нашел, не работает в моем случае, возможно, потому что мое число не является константным. Вот код решения, который я нашел: ```cpp template<unsigned long long Max> struct RequiredBits { enum { value = Max <= 0xff ? 8 : Max <= 0xffff ? 16 : Max <= 0xffffffff ? 32 : 64 }; }; template<int bits> struct SelectInteger_; template<> struct SelectInteger_ <8> { typedef uint8_t type; }; template<> struct SelectInteger_<16> { typedef uint16_t type; }; template<> struct SelectInteger_<32> { typedef uint32_t type; }; template<> struct SelectInteger_<64> { typedef uint64_t type; }; template<unsigned long long Max> struct SelectInteger : SelectInteger_<RequiredBits<Max>::value> {}; ``` Моя проблема в том, что этот код не работает для моего случая, которым является число, не являющееся константой. Как я могу изменить этот код, чтобы он работал для неконстантного числа?
Чтобы изменить код, чтобы он работал для неконстантного числа, вы можете использовать шаблонные параметры вместо константных значений. Вам потребуется перегрузить шаблон "SelectInteger" для неконстантного числа и передать его в качестве аргумента шаблона "RequiredBits". Вот пример кода: ```cpp template<unsigned long long Max> struct RequiredBits { enum { value = Max <= static_cast<unsigned long long>(std::numeric_limits<uint8_t>::max()) ? 8 : Max <= static_cast<unsigned long long>(std::numeric_limits<uint16_t>::max()) ? 16 : Max <= static_cast<unsigned long long>(std::numeric_limits<uint32_t>::max()) ? 32 : 64 }; }; template<unsigned long long Max> struct SelectInteger_; template<unsigned long long Max> struct SelectInteger { typedef typename SelectInteger_<RequiredBits<Max>::value>::type type; }; template<> struct SelectInteger<0> { typedef uint8_t type; // наименьший тип, если Max = 0 }; template<> struct SelectInteger_<8> { typedef uint8_t type; }; template<> struct SelectInteger_<16> { typedef uint16_t type; }; template<> struct SelectInteger_<32> { typedef uint32_t type; }; template<> struct SelectInteger_<64> { typedef uint64_t type; }; ``` Вы можете вызвать SelectInteger с неконстантным значением, например: ```cpp unsigned long long n = 12345; typedef SelectInteger<n>::type SmallestType; // SmallestType будет наименьшим типом, вмещающим число n ``` Теперь код должен работать для неконстантных чисел.
Совет: Выделите массив байт и кастуйте указатель к нужному типу, используя union. Убедитесь, что alignment массива соответствует требованиям (например, кратен 8 байтам), чтобы избежать замедления.
Если выделите массив байт и приведете указатель к нужному типу, используя union, то замедления не будет, при условии, что alignment массива соответствует требованиям (например, кратен 8 байтам).