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

Почему разрешены статические константы?

У меня есть класс, который по существу просто содержит кучу постоянных определений, используемых в моем приложении. По какой-то причине, однако, long компиляция, но float не выполняет:

class MY_CONSTS
{
public :
    static const long   LONG_CONST = 1;      // Compiles 
    static const float FLOAT_CONST = 0.001f; // C2864
};

Дает следующую ошибку:

1>c:\projects\myproject\Constant_definitions.h(71) : error C2864: 'MY_CONSTS::FLOAT_CONST' : only static const integral data members can be initialized within a class

Я что-то пропустил?

4b9b3361

Ответ 1

Чтобы ответить на фактический вопрос, который вы задали, "потому что стандарт говорит так".

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

Стандарт С++ Стандарт Раздел 9.2 "Члены класса", пункт 4:

Участник-декларатор может содержать константный инициализатор, только если он объявляет статический член (9.4) of const интегральное или const перечисление тип, см. 9.4.2.

Раздел 9.4.2 "Элементы статических данных", пункт 2:

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

Ответ 2

Вы должны инициализировать их в теле одного из ваших файлов cpp:

class MY_CONSTS
{
public :
    static const long   LONG_CONST = 1;      // Compiles 
    static const float FLOAT_CONST;
};

const float MY_CONSTS::FLOAT_CONST = 0.001f;

Ответ 3

См. Объяснение Stroustrup. Соответствующая цитата:

Класс обычно объявляется в заголовочный файл и заголовочный файл обычно включаются во многие единицы перевода. Однако, чтобы избежать сложные правила компоновщика, С++ требует что каждый объект имеет уникальную определение. Это правило будет нарушено если С++ допускает определение класса в классе объекты, которые необходимо сохранить в память как объекты. См. D & E для объяснение компромиссов дизайна С++.

Ответ 4

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

Из памяти, в С++ 0X, понятие постоянного выражения было расширено, и поэтому ваш код будет действительным (но он не указан в результате константных выражений с плавающей точкой одинаковы при оценке во время выполнения или во время компиляции).

Ответ 5

как насчет:

class MY_CONSTS
{
public :
    static const long   LONG_CONST;
    static const float FLOAT_CONST;
};

const long MY_CONSTS::LONG_CONST = 1;
const float MY_CONSTS::FLOAT_CONST = 0.001f;

(хотя я не могу дать никакого объяснения этому конкретному случаю...)

Ответ 6

Из стандарта 9.4.2/4

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

И 5.19/1:

В нескольких местах требуется C + + выражения, которые интегральная или континуальная константа: as (8.3.4, 5.3.4), как случай выражения (6.4.2), как битовое поле длины (9.6), в качестве счетчика инициализаторы (7.2), как статический член инициализаторы (9.4.2) и как интегральные или перечисление непигового шаблона аргументы (14.3). константа-выражение: условное выражение Интеграл константное выражение может включать только литералы (2.13), счетчики, const переменные или статические данные интегральные или перечисляемые типы инициализируется постоянными выражениями (8.5), несимметричные шаблонные параметры интегральные или перечисляемые типы и sizeof выражения. Плавающий литералы (2.13.3) могут появляться только в том случае, если их отливают в интегральные или типы перечисления. Только тип преобразования в интеграл или перечисление типы могут использоваться. В частности, кроме выражения sizeof, функции, объекты класса, указатели или ссылки не должны