您不必在声明时为mySecondVar 指定初始化程序。初始化器本身也不需要是constexpr。
这意味着如果我们尝试像这样定义myFirstVar:
class MyClass {
static constexpr int myFirstVar;
};
int MyClass::myFirstVar = 1;
或者像这样:
#include <cstdlib>
class MyClass {
static constexpr int myFirstVar = rand();
};
无论哪种方式,它都是不正确的。 constexpr 语义需要它并且有充分的理由。
inline 说明符方法允许我们在标头本身中包含一个静态变量定义,而初始值设定项不是constexpr;或者如果初始化程序相当复杂,它不必在类定义本身中。
所以这是 C++17 中一个完全有效的标头:
#include <cstdlib>
class MyClass {
static const int mySecondVar;
};
inline const int MyClass::mySecondVar = rand();
该标准向我们保证,所有包含标头的翻译单元都会看到相同的变量值,即使我们在运行时才知道它是什么。
它主要是一个库编写器工具。假设您的库只是标题。那么在过去,如果您需要这样定义的静态常量,您有什么选择?
好吧,您可以在库中附带一个目标文件。它将从只包含常量定义的翻译单元编译。现在该库不再是仅标头了。
或者您可以改用内联函数。内联变量效果可以通过以下方式实现:
class MyClass {
static inline int mySecondVar();
};
inline int MyClass::mySecondVar() {
static const int value = rand();
return value;
}
但它隐藏在语法墙后面,并用函数调用运算符掩盖了本质上是常量的内容。