C++11, целочисленный тип определяется диапазоном?
Таким образом, этот вопрос возник, выполняя довольно простое кодирование, рассмотрим следующее;
for(unsigned int x=0x00000000; x<0xFFFFFFFF; x++)
{
// ...
}
Приведенный выше код работает, как и ожидалось, предполагая 'sizeof(unsigned int) >= 4', однако, как мы знаем, на некоторых платформах это может быть не так, поэтому я заинтересован в чем-то подобном;
for(RangeBasedInt<0x00000000, 0xFFFFFFFF>::type x=0x00000000; x<0xFFFFFFFF; x++)
{
// ...
}
Где RangeInt - это шаблон, а type - наименьший целочисленный тип, достаточно большой, чтобы содержать диапазон значений от MINIMUM (0x00000000) до MAXIMUM (0xFFFFFFFF);
template<int MINIMUM, int MAXIMUM>
struct RangeBasedInt
{
// Type based upon MINIMUM and MAXIMUM
typedef /* MAGIC */ type;
};
Итак, вопрос в том, насколько это просто;
- Это реализовано где-то в стандартной библиотеке?
- Если нет, то есть ли библиотека, реализующая это, или мне придется создавать свою собственную на основе std::numeric_limits?
1 ответ
Это действительно легко реализовать самостоятельно. Так легко сказать, что это реализовано на языке:
typedef decltype(0xFFFFFFFF) RangeBasedInt;
for(RangeBasedInt x=0x00000000; x<0xFFFFFFFF; x++)
{
// ...
}
2.14.2 [lex.icon] утверждает, что тип целочисленного литерала является наименьшим типом, который может содержать значение. Так что если int
может держать 0xFFFFFFFF
на вашей машине, RangeBasedInt
может быть int
, На моей машине это unsigned int
,
Для этого конкретного предела (0xFFFFFFFF
), стандарт гарантирует, что он может быть представлен одним из встроенных целочисленных типов. ULONG_MAX
должно быть не менее 4294967295 (0xFFFFFFFF), и ULLONG_MAX
должно быть не менее 18446744073709551615 (0xFFFFFFFFFFFFFFFF).
Обновить
Я исправлен Skeen по техническим причинам. Таблица 6 в [lex.icon] фактически не говорит "наименьший тип". Это фактически говорит о том, что если литерал является восьмеричной или шестнадцатеричной константой, то это будет первый тип в следующем списке, в котором его значение может быть представлено:
int
unsigned int
long int
unsigned long int
long long int
unsigned long long int
В таблице приводятся разные списки в зависимости от того, является ли литерал десятичным или нет, и суффикс ли он или нет. Я определенно перефразировал, когда сказал "самый маленький". Для точных деталей, пожалуйста, обратитесь к действующему стандарту, а не к SO-ответу (я или кто-либо еще) На момент написания этой статьи последний проект C++1y - N3691.