C ++ 17允许定义静态成员变量:
class X {
public:
static inline int i = 8;
};
要求inline
规范背后的理由是什么?为什么不简单地允许程序员编写
static int i = 8;
在课堂上?
答案 0 :(得分:12)
没有inline
,它只是明确声明为声明。正如[class.static.data]/2
在其类中声明非内联静态数据成员 定义不是定义,可能是其他不完整的类型 比cv void。静态数据成员的定义不是 类定义中的内联定义应出现在命名空间中 封闭成员类定义的范围。
基本原理很可能是保持遗留代码的完整性和有效性。回想一下,我们可以永远地初始化类定义本身中的积分常量。但是使用它们仍然需要在一些翻译单元中进行课外定义。
因此,隐式内联使这些变量在现有代码库中可能会出现问题。在添加核心语言功能时,委员会一直在考虑向后兼容性。
例如,请考虑这个有效的C ++ 03类定义:
struct foo {
static const int n = 3;
double bar[n];
};
n
可以用作常量表达式来定义bar
的范围,并且它不被视为使用odr。现在我们把它写成constexpr
1 ,但是上面的内容仍然有效。但可能是n
必须使用odr的情况(想象它的地址,或绑定它的引用等)。它们可能并不多,也可能不常见,但是某些API有疯狂的要求,最终会导致这种情况的发生。
const int foo::n;
出现在某个翻译单元中。
现在,如果static inline int i = 8;
突然隐含inline
,则上面的定义(即现有代码库中的定义)将违反了odr。现在以前格式良好的代码是不正确的。因此,最好只允许显式 inline
在此处生效,因为只有新代码才会实际拥有它。
<子>
1 有人可能认为static constexpr
变量可能有相同的问题(但它们是隐式内联的)。但是IIRC的原始措辞允许这种改变而不会破坏现有的代码。除了名字之外,它基本上已经“内联”了。
子>