16

在 C++ 中,static成员可能不会在类主体中初始化,但以下情况除外:

  • staticconst整数类型的成员可以
  • staticconstexpr文字类型的成员必须

你能解释为什么这些例外吗?

此外,这也成立:

即使const static在类主体中初始化了数据成员,该成员通常也应该在类定义之外定义。

这一点我完全不明白。这个额外的定义有什么意义?

只是想在这里获得一些直觉。

4

1 回答 1

8

为什么类定义中可以有初始化器?

关于静态数据成员const的两个例外:constexpr

[class.static.data]/3

[ 注意:在这两种情况下,成员都可能出现在常量表达式中。——尾注]

即使用初始化器,您可以在常量表达式中使用它们,例如

struct s
{
    static std::size_t const len = 10;
    int arr[len];
};
std::size_t const s::len;

如果len没有在类定义中初始化,编译器就不能轻易知道它在下一行中的值来定义arr.

有人可能会争论在类定义中允许非const、非constexpr静态数据成员的初始化器,但这可能会干扰初始化顺序:

[basic.start.init]/2

显式专门化的类模板静态数据成员的定义已排序初始化。其他类模板静态数据成员(即,隐式或显式实例化的特化)具有无序初始化。其他具有静态存储持续时间的非局部变量已按顺序初始化。

也就是说,包括初始化程序在内的定义的顺序很重要。const非本地对象的(动态)初始化顺序仅在翻译单元中定义,这是必须定义包括非、非constexpr静态数据成员的初始化程序的另一个原因。


这个额外的定义有什么意义?

这已经在 IMO 的评论中得到了回答。您可能想要添加 ODR,也就是说,作为具有外部链接的名称,静态数据成员必须(仅)在一个翻译单元中定义(如果它是 ODR 使用的)。由程序员来选择这个翻译单元。

于 2013-05-04T12:26:19.520 回答