在类定义中初始化的静态整数数据成员可以声明为 const
或 constexpr
,但在类定义中初始化的非整数静态数据成员必须是 constexpr
:
class MyClass {
static const int w = 5; // okay
static constexpr int x = 5; // okay
static const float y = 1.5; // error!
static constexpr float z = 1.5; // okay
};
有人知道为什么不允许y的声明吗?标准中将其定为非法的部分是9.4.2 / 3,但为什么它是非法的?
3 回答
在C 11之前,您无法在类声明中初始化非整数/枚举类型的静态成员(但您可以在类声明之外) . 管理
constexpr
的规则带有前向,但允许您在类声明中使用constexpr
初始化它(因此您不再需要如下代码):这条规则的一个副作用是简化你的类结构,而不是让它变得丑陋(如上面的代码) .
在C11添加
constexpr
之前的情况之一的原因之一是标准未指定如何实现浮点(它留给处理器/架构 - 例如,当你说float x = 1.6f
时,它实际上是1.6000000000024
在大多数系统上) .float
有点难以描述其动机,但想象一下 class 成员:在这种情况下,
a
可能会有一些非平凡的结构,可能会违反(或至少非常复杂)单定义规则 . 因为constexpr
已经保证了限制性编译时属性,b
的复制构造函数也必须是constexpr
,因此保证在编译时返回一个定义良好的值(并且 NOT 违反了one-definition-rule)为什么
float
表现出这种行为我认为只是出于遗留原因,因为float
从来没有传统上像这样初始化("because the standard says so"),所以他们在constexpr
的保护下 grab 了初始化static
const
float
成员 .这可能是因为非整数i也可能包含像char这样的数据类型,这就是为什么你不能使它们保持不变并需要常量表达的原因 . 但是在积分的情况下,你可以使它们成为常量表达式或常量 . 因此,由于char只能是常量表达式,因此对于所有非整数值都是非法的 .