2009-12-14 1 views
2

Есть ли простой, чистый способ определения во время компиляции значений max и min для переменной некоторой (иначе неизвестной в данный момент) целочисленной переменной или типом? Использование шаблонов?Значения Min и Max для целочисленной переменной во время компиляции в 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 
+0

Значение переменной не может быть известно во время компиляции, но константы могут. –

+0

«Значение» переменной не требуется в приведенном выше коде. Но это не тип переменной, как в моем примере, известный во время компиляции. Эти переменные не являются полиморфными классами, а всего лишь одним из основных целых типов. Или я что-то упускаю (очень возможно). Я думаю, что у меня есть numeric_limits, работающий для случая, когда имя используется напрямую. Теперь я могу сделать что-то вроде: e = numeric_limits :: max(); ? – Harvey

+0

Несомненно, тип «a» или «b» известен компилятору во время компиляции. В противном случае компилятор не сможет генерировать код, используя эти переменные вообще. – Harvey

ответ

13

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

+5

AFAIK, это не время компиляции *, хотя (если сам ОП осознает, что именно он хочет). – UncleBens

+1

Не время компиляции, но довольно близко к нему, если оптимизация включена. –

+5

RaphaelSP: если требуется время компиляции, например, для параметра шаблона или перечислителя, то не имеет значения, какие оптимизаторы включены - либо это выражение, либо оно не является. Сравните с constexprs в C++ 0x. – 2009-12-14 15:41:59

3

Смотрите этот вопрос maximum value of int - вы также можете использовать «мин» в тех местах, где ответы, используемые «Макс»

0

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

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

+0

Неправильно. Это не время компиляции. –

+0

Верно, и код клиента выше не мог отличить оценку во время выполнения от времени компиляции.Все реализации для 'numeric_limits', которые я видел, - это функции, отображающие константы, определенные во время компиляции, но я не думаю, что это была ошибка, которую стандарт предоставляет этим значениям возможность раскрываться через функции, а не постоянные значения элементов - в в частности, для размещения типов с плавающей точкой или некоторых других не-ICE. – seh

0

Если у вас есть доступ к 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, и все это может быть определено во время компиляции.