41

以下代码的问题是“const double”类型的静态成员不能具有类内初始化程序。为什么仅适用于以下代码中的“const double”?请帮我。

class sample{
   static const char mc = '?';
   static const double md = 2.2;
   static const bool mb = true;
};
const char sample::mc;
const double sample::md;
const bool sample::mb;
int main(){
}
4

3 回答 3

61

C++03语言标准实现的逻辑基于以下原理。

在 C++ 中,初始化程序是对象定义的一部分。您在类中为静态成员编写的内容实际上只是一个声明。因此,正式地说,直接在类中为任何静态成员指定初始化程序是“不正确的”。它与语言的一般声明/定义概念相反。无论您在类中声明的任何静态数据都必须在以后定义。这就是您有机会指定初始化程序的地方。

该规则的一个例外是静态整型常量,因为 C++ 中的此类常量可以形成整型常量表达式 (ICE)。ICE 在语言中发挥着重要作用,为了让它们按预期工作,整数常量的值必须在所有翻译单元中可见。为了使某个常量的值在所有翻译单元中可见,它必须在声明点可见。为了实现这一点,该语言允许直接在类中指定初始化程序。

此外,在许多硬件平台上,常量整数操作数可以直接嵌入到机器命令中。或者可以完全消除或替换常数(例如,8可以将乘以实现为移位3)。为了便于生成具有嵌入式操作数和/或各种算术优化的机器代码,重要的是让整数常量的值在所有翻译单元中可见。

非整数类型没有任何类似于 ICE 的功能。此外,硬件平台通常不允许将非整数操作数直接嵌入到机器命令中。出于这个原因,上述“规则的例外”不会扩展到非整数类型。它只会一事无成。

于 2012-12-04T06:43:37.890 回答
29

编译器让我使用constexpr而不是const

static_consts.cpp:3:29: error: ‘constexpr’ needed for in-class initialization of static data member ‘const double sample::md’ of non-integral type [-fpermissive]
static_consts.cpp:7:22: error: ‘constexpr’ needed for in-class initialization of static data member ‘const double sample::md’ of non-integral type [-fpermissive]

我刚刚接受了offer:

class sample{
   static const char mc = '?';
   static constexpr double md = 2.2;
   static const bool mb = true;
};
const char sample::mc;
const bool sample::mb;
int main(){
}

现在它编译得很好(C++11)。

于 2016-03-15T11:47:48.797 回答
13

在 C++11 之前,只有const整数类型可以在类定义中直接初始化。这只是标准施加的限制。

对于 C++11,这不再适用。

于 2012-12-04T06:30:26.257 回答