Автоматически выбирать тип переменной, достаточно большой, чтобы содержать указанное число - PullRequest
54 голосов
/ 12 августа 2011

Есть ли способ в C ++ определить тип, который достаточно большой, чтобы содержать не более определенного числа, предположительно, с использованием некоторого умного кода шаблона.Например, я хочу иметь возможность написать: -

Integer<10000>::type dataItem;

И разрешить ли этот тип наименьшему типу, который достаточно большой, чтобы содержать указанное значение?

Справочная информация: мне нужногенерировать определения переменных с использованием сценария из внешнего файла данных.Я думаю, я мог бы заставить скрипт посмотреть значения, а затем использовать uint8_t, uint16_t, uint32_t и т. Д. В зависимости от значения, но кажется, что элегантный выглядит более сложным, чтобы встроить размерсгенерированный код C ++.

Я не вижу способа создать шаблон, который бы мог это сделать, но, зная шаблоны C ++, я уверен, что есть способ.Есть идеи?

Ответы [ 12 ]

1 голос
/ 12 августа 2011

Вы имеете в виду что-то вроде:

template <int MAX>
struct Integer {
    typedef typename Integer<MAX+1>::type type;
};

template <>
struct Integer<2147483647> {
    typedef int32_t type;
};

template <>
struct Integer<32767> {
    typedef int16_t type;
};

template <>
struct Integer<127> {
    typedef int8_t type;
};

И, возможно, другая шаблонная структура для UnsignedInteger.

Возможно, вы даже можете использовать numeric_limits вместо жестко закодированных значений.

0 голосов
/ 24 января 2017

Нет перечисления, просто введитеdef.

#include<stdio.h>
#include<stdint.h>

template <unsigned long long V> struct valuetype
{
    typedef typename valuetype<(V & (V-1)) ? (V & (V-1)) : (V >> 1)>::val val;
};
template <> struct valuetype<(1ull << 0)> { typedef uint8_t val; };
template <> struct valuetype<(1ull << 8)> { typedef uint16_t val; };
template <> struct valuetype<(1ull << 16)> { typedef uint32_t val; };
template <> struct valuetype<(1ull << 32)> { typedef uint64_t val; };

int main ()
{
    valuetype<123>::val a = ~0;
    printf ("%llu\n", (unsigned long long) a);  
    valuetype<456>::val b = ~0;
    printf ("%llu\n", (unsigned long long) b);  
    valuetype<123456>::val c = ~0;
    printf ("%llu\n", (unsigned long long) c);  
    valuetype<123456123>::val d = ~0;
    printf ("%llu\n", (unsigned long long) d);
    valuetype<123456123456>::val e = ~0;
    printf ("%llu\n", (unsigned long long) e);
    return 0;
}

255
65535
4294967295
4294967295
18446744073709551615

...