Использование numeric_limits:: max() в постоянных выражениях
Я хотел бы определить внутри класса константу, значение которой является максимально возможным int. Что-то вроде этого:
class A
{
...
static const int ERROR_VALUE = std::numeric_limits<int>::max();
...
}
Это объявление не может скомпилироваться со следующим сообщением:
numeric.cpp: 8: ошибка: 'std:: numeric_limits:: max()' не может появляться в константном выражении numeric.cpp: 8: ошибка: вызов функции не может появляться в константном выражении
Я понимаю, почему это не работает, но две вещи выглядят странно для меня:
-
Мне кажется естественным решение использовать значение в постоянных выражениях. Почему разработчики языка решили сделать функцию max() таким образом, чтобы не разрешать это использование?
-
В статье 18.2.1 указано, что
Для всех членов, объявленных static const в шаблоне numeric_limits, специализации должны определять эти значения таким образом, чтобы они использовались как интегральные константные выражения.
Не означает ли это, что я должен использовать его в своем сценарии и не противоречит ли это сообщению об ошибке?
Спасибо.
Ответы
Ответ 1
В то время как текущий стандарт не поддерживает поддержку здесь, для интегральных типов Boost.IntegerTraits дает постоянные времени компиляции const_min
и const_max
.
Проблема возникает из § 9.4.2/4:
Если статический член данных имеет тип const const или const, его объявление в определении класса может указывать константу-инициализатор, который должен быть интегральным постоянным выражением (5.19). В этом случае член может появляться в интегральных постоянных выражениях.
Обратите внимание, что он добавляет:
Элемент все еще должен быть определен в области пространства имен, если он используется в программе, а определение области пространства имен не должно содержать инициализатор.
Как уже упоминалось ранее, numeric_limit
min()
и max()
просто не являются неотъемлемыми постоянными выражениями, то есть константами времени компиляции.
Ответ 2
Похож на недостаток...
В С++ 0x numeric_limits
будет указано все, помеченное знаком constexpr
, что означает, что вы сможете использовать min()
и max()
как константы времени компиляции.
Ответ 3
Вы хотите:
#include <limits>
struct A {
static const int ERROR_VALUE;
};
const int A::ERROR_VALUE = std::numeric_limits<int>::max();
Поместите класс /struct в заголовок и определение в файл .cpp.
Ответ 4
Это не противоречит, потому что max
не определен static const
. Это просто статическая функция-член. Функции не могут быть const, а статические функции-члены также не могут иметь константу.
В двойной версии ограничений существует также double max()
, а в С++ 03 не будет сказано static double const max = ...
. Чтобы быть последовательным, max()
является функцией для всех версий шаблона ограничения.
Теперь он знал, что max()
не может быть использован как это плохо, и С++ 0x уже решает его, сделав его функцией constexpr
, что позволяет предлагать вам использование.
Ответ 5
- Я постараюсь ответить вам так же, как я понял из вашего вопроса:
1- Если вы хотите, чтобы статическая константа int в вашей программе была инициализирована с помощью функции:
int Data()
{
return rand();
}
class A
{
public :
static const int ee;
};
const int A::ee=Data();
Это работает на VS 2008
2- Если вы хотите получить максимальное и минимальное количество для данного типа данных, используйте эти определения
INT_MAX, INT_MIN, LONG_MAX и т.д.
3 Если вам нужно использовать этот тип шаблона wrt, тогда
жесткий код сами шаблоны
template<>
int MaxData()
{
return INT_MAX;
}
и
template<>
long MaxData()
{
return LONG_MAX ;
}
и назовите их следующим образом
int y=MaxData<int>();
4- и если вы имеете дело только с бинарными представленными типами, то используйте это:
template <class T>
T MaxData(){
return ~(1<<((sizeof(T)*8)-1));
}
и этот
template <class T>
T MinData(){
return (1<<((sizeof(T)*8)-1));
}
Надеюсь, это поможет вам.