为什么不允许使用静态的const float?

我有一个类本质上只是持有一堆通过我的应用程序使用的常量定义。 不过由于某种原因, 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 

我错过了什么吗?

回答你问的实际问题:“因为标准是这样说的”。

只有静态,常量, 整型 (包括枚举)的variables可以在类声明中初始化。 如果一个编译器支持浮点数的在线初始化,它是一个扩展。 正如其他人指出的那样,处理静态,常量,非整型variables的方法是在类的相应源文件(而不是头)中定义和初始化它们。

C ++标准第9.2节“类成员”第4项:

成员声明 只有在声明了const型或const枚举types的静态成员(9.4)时才能包含常量初始值设定项 ,见9.4.2。

第9.4.2节“静态数据成员”项目2:

如果一个静态数据成员是const型或者const枚举types,那么它在类定义中的声明可以指定一个常数初始值设定项 ,它应该是一个整型常量expression式(5.19)。 在这种情况下,成员可以出现在整型常量expression式中。 如果在程序中使用成员,名字空间范围定义中不应该包含初始化符,则该成员仍应定义在名称空间范围内。

你应该在你的一个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; 

见Stroustrup的解释 。 相关报价:

一个类通常在头文件中声明,而头文件通常包含在许多翻译单元中。 但是,为了避免复杂的链接器规则,C ++要求每个对象都有唯一的定义。 如果C ++允许将需要作为对象存储在内存中的实体的类定义中断,那么该规则将被破坏。 请参阅D&E以获取有关C ++devise权衡的解释。

其他人给出的标准措辞下的基本原理同样是模板参数不能为浮点数的。 为了获得一致的结果,您需要编译器实现与编译时完成的评估相同的评估,对于交叉编译器以及程序以舍入模式进行播放的情况,这可能会很复杂。

从内存中,在C ++ 0X中,常量expression式的概念已经被扩展,所以你的代码将是有效的(但是在浮点结果中没有指定常量expression式在运行时或编译时)。

关于什么:

 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; 

(虽然,我不能给出这个具体情况的任何解释…)

从标准9.4.2 / 4

如果静态数据成员是const整型或常量枚举types的,则它在类定义中的声明可以指定一个常数初始值设定项,它应该是一个整型常量expression式(5.19)。 在这种情况下,成员可以出现在整型常量expression式中。 如果在程序中使用成员,则该成员仍应在名称空间作用域中定义,并且名称空间作用域定义不应包含初始值设定项。

和5.19 / 1:

在一些地方,C ++需要求值为整数或枚举常量的expression式:作为数组边界(8.3.4,5.3.4),作为expression式(6.4.2),作为位长度(9.6),作为枚举器初始值设定项(7.2),静态成员初始值设定项(9.4.2)以及整型或枚举非types模板参数(14.3)。 常量expression式:条件expression式一个整型常量expression式可以只包含用常量expression式(8.5)初始化的整型或枚举types的文本(2.13),枚举器,常量variables或静态数据成员,积分或枚举的非types模板参数types和sizeofexpression式。 浮动文字(2.13.3)只有在转换为整型或枚举types时才会出现 。 只能将types转换为整型或枚举types。 特别是,除了sizeofexpression式,函数,类对象,指针或引用不应该