Подтвердить что ты не робот

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

    Не означает ли это, что я должен использовать его в своем сценарии и не противоречит ли это сообщению об ошибке?

Спасибо.

4b9b3361

Ответ 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));
}

Надеюсь, это поможет вам.