Минимальное и максимальное значения для целочисленной переменной во время компиляции в C++

Есть ли простой, чистый способ определения во время компиляции максимального и минимального значений для переменной некоторой (иначе неизвестной в данный момент) целочисленной переменной или типа? Используя шаблоны?

Например:

// Somewhere in a large project is:
typedef unsigned long XType;
typedef char YType;
// ...

// Somewhere else
   XType a;
   YType b;
   LONGLONG c,d,e,f;
   c = MinOfType(a); // Same as c = 0;
   d = MaxOfType(a); // Same as d = 0xffffffff;
   e = MinOfType(b); // Same as e = -128;
   f = MaxOfType(b); // Same as f = 127;
// Also would be nice
   e = MinOfType(YType); // Same as e = -128; // Using the typename directly
// Or perhaps
   e = MinOfType<YType>(); // Same as e = -128; // Using the typename directly

person Harvey    schedule 14.12.2009    source источник
comment
Значение переменной не может быть известно во время компиляции, но константы могут.   -  person Steve Guidi    schedule 14.12.2009
comment
Значение переменной не требуется в приведенном выше коде. Но не известен ли тип переменной, как в моем примере, во время компиляции. Эти переменные не являются полиморфными классами, а просто одним из основных целочисленных типов. Или я что-то пропустил (очень возможно). Я думаю, что numeric_limits работает для случая, когда имя типа используется напрямую. Теперь я могу сделать что-то вроде: e=numeric_limits‹TypeOf(b)›::max(); ?   -  person Harvey    schedule 15.12.2009
comment
Конечно, тип a или b известен компилятору во время компиляции. В противном случае компилятор вообще не смог бы генерировать код с использованием этих переменных.   -  person Harvey    schedule 15.12.2009


Ответы (5)


Ознакомьтесь с разделом улучшение целочисленных_признаков.

person moonshadow    schedule 14.12.2009

Используйте std::numeric_limits, он предназначен именно для такого типа требований. Вы можете взглянуть на этот пример для использование.

person Naveen    schedule 14.12.2009
comment
Насколько я знаю, это не время компиляции (если сам ОП понимает, чего именно он хочет). - person UncleBens; 14.12.2009
comment
Не время компиляции, но довольно близко к нему, если включена оптимизация. - person Raphaël Saint-Pierre; 14.12.2009
comment
RaphaelSP: если на самом деле требуется время компиляции, например, для параметра шаблона или перечислителя, то не имеет значения, какие оптимизации включены — либо выражение включено, либо нет. Сравните с constexprs в C++0x. - person ; 14.12.2009
comment
Хорошая точка зрения. Я только что перевел время компиляции на быстрое (учитывая, что фрагмент кода не делает разумного использования бита времени компиляции). - person Raphaël Saint-Pierre; 14.12.2009

См. этот вопрос максимальное значение int - вы также можете использовать "min" в местах, где ответы использовали "макс"

person Community    schedule 14.12.2009

Если у вас есть доступ к c++11, вы можете использовать комбинацию decltype и std::numeric_limits. Переписывание вашего примера кода будет выглядеть так:

#include <limits>

typedef unsigned long XType;
typedef char YType;

XType a;
YType b;
LONGLONG c,d,e,f;
c = std::numeric_limits< decltype(a) >::min(); // Same as c = 0;
d = std::numeric_limits< decltype(a) >::max(); // Same as d = 0xffffffff;
e = std::numeric_limits< decltype(b) >::min(); // Same as e = -128;
f = std::numeric_limits< decltype(b) >::max(); // Same as f = 127;
e = std::numeric_limits< YType >::min(); // Same as e = -128; // Using the typename directly

decltype будет извлекать тип из выражения, в данном случае захватывая тип переменной, и позволит вам использовать это в других местах, которые ожидают тип, такой как шаблон. И все это происходит во время компиляции, так что вы можете назначить его constexpr.

constexpr decltype(a) g = std::numeric_limits< decltype(a) >::min();

Здесь g будет того же типа, что и a, будет иметь значение 0, и все это будет определено во время компиляции.

person kalaxy    schedule 21.09.2012

Включите заголовок <limits> для доступа к классу шаблона std::numeric_limits. Числовой тип вашей переменной используется для поиска специализации этого класса шаблона, которая предоставит максимальное значение через функцию max() и минимальное значение через min()< /a>, в дополнение к нескольким другим аспектам типа.

Обратите внимание, что интерпретация минимум отличается для целочисленных типов и типов с плавающей запятой. Для первого это самое отрицательное значение для знакового типа и ноль для беззнакового типа, но для второго это наименьшее представимое значение, очень близкое к нулю.

person seh    schedule 14.12.2009
comment
Неправильный. Это не время компиляции. - person Alexey Malistov; 14.12.2009
comment
Верно, и приведенный выше клиентский код не мог отличить оценку во время выполнения от времени компиляции. Все реализации для numeric_limits, которые я видел, представляют собой функции, раскрывающие константы, определенные во время компиляции, но я не думаю, что было ошибкой то, что стандарт требует, чтобы эти значения отображались через функции, а не константные значения членов, в частности, для размещения типов с плавающей запятой или некоторых других не-ICE. - person seh; 14.12.2009