Используя numeric_limits:: макс. () в константных выражениях

Я хотел бы определить в классе константу, какое значение является максимальным возможным интервалом Что-то вроде этого:

class A
{
    ...
    static const int ERROR_VALUE = std::numeric_limits<int>::max();
    ...
}

Этому объявлению не удается скомпилировать со следующим сообщением:

числовой cpp:8: ошибка: 'станд.:: numeric_limits:: макс. ()' не может появиться в числовом cpp:8 константном выражении: ошибка: вызов функции не может появиться в константном выражении

Я понимаю, почему это не работает, но две вещи выглядят странными мне:

  1. Это кажется мне естественным решением использовать значение в константных выражениях. Почему разработчики языка решали сделать макс. () функцию, таким образом не позволяющую это использование?

  2. Спецификация требует в 18.2.1 это

    Поскольку все участники объявили статическую константу в шаблоне numeric_limits, специализации должны определить эти значения таким способом, которым они применимы как интегральные константные выражения.

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

Спасибо.

29
задан jww 23 December 2016 в 14:56
поделиться

5 ответов

Хотя текущий стандарт здесь не поддерживает, для целочисленных типов Boost.IntegerTraits дает вам константы времени компиляции const_min и const_max .

Проблема возникает из §9.4.2 / 4 :

Если статический член данных имеет тип константного целого или константного перечисления, его объявление в определении класса может указывать константный инициализатор, который должно быть интегральным постоянным выражением (5.19). В этом случае член может появляться в целочисленных постоянных выражениях.

Обратите внимание, что он добавляет:

Член должен быть определен в области пространства имен, если он используется в программе, а определение области пространства имен не должно содержать инициализатор.

Как уже упоминалось, numeric_limit s min () и max () просто не являются целочисленными константами, т.е. константами времени компиляции.

16
ответ дан 28 November 2019 в 01:32
поделиться

Вы хотите:

#include <limits>

struct A {
static const int ERROR_VALUE;
}; 

const int A::ERROR_VALUE = std::numeric_limits<int>::max();

Поместите класс / структуру в заголовок, а определение в файл .cpp.

14
ответ дан 28 November 2019 в 01:32
поделиться

Это не противоречит, потому что max не определено static const . Это просто статическая функция-член. Функции не могут быть константными, и у статических функций-членов также не может быть констант, прикрепленных справа.

Также есть double max () в двойной версии ограничений, а в C ++ 03 не получится сказать static double const max = ... . Чтобы быть последовательным, max () - это функция для всех версий шаблона лимита.

Теперь известно, что невозможность использования max () таким образом - это плохо, и C ++ 0x уже решает эту проблему, сделав ее функцией constexpr , что позволяет ваше предлагаемое использование.

4
ответ дан 28 November 2019 в 01:32
поделиться
  • Я постараюсь ответить вам, насколько я понял из вашего вопроса:

1- Если вы хотите, чтобы в вашей программе статическая const 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));
}

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

2
ответ дан 28 November 2019 в 01:32
поделиться

Похоже на небольшую неисправность ...

В C ++ 0x, numeric_limits все будет помечено constexpr , что означает, что вы сможете использовать min () и max () в качестве констант времени компиляции.

17
ответ дан 28 November 2019 в 01:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: