静态constexpr和C++ 17中的静态内联变量有什么区别?

fen*_*fen 50 c++ c++17

使用C++ 17,我们得到内联变量.

其中一个用途是在类中定义常量字段.

那么这两个常量定义之间的区别是什么:

class MyClass {
    static constexpr int myFirstVar = 10;
    static const inline int mySecondVar = 100;
};
Run Code Online (Sandbox Code Playgroud)

当然constexprmyFirstVar隐式内联.

什么是更好的选择,使用constexprinline

注意:当你不需要constness时,那就inline更容易了.随着constexpr你没有这样的选择.

Sto*_*ica 51

您不必mySecondVar在声明时指定初始化程序.初始化程序也不是必需的constexpr.

这意味着如果我们尝试定义myFirstVar如下:

class MyClass {
    static constexpr int myFirstVar;
};

int MyClass::myFirstVar = 1;
Run Code Online (Sandbox Code Playgroud)

或者像这样:

#include <cstdlib>

class MyClass {
    static constexpr int myFirstVar = rand();
};
Run Code Online (Sandbox Code Playgroud)

无论如何,它都是不合理的.constexpr语义要求它并且有充分的理由.

inline说明符方法使我们能够包括在报头本身的静态变量的定义,而不初始化福祉constexpr; 或者如果初始化程序相当复杂,则不必在类定义本身中.

所以这是C++ 17中完全有效的标题:

#include <cstdlib>

class MyClass {
    static const int mySecondVar;
};

inline const int MyClass::mySecondVar = rand();
Run Code Online (Sandbox Code Playgroud)

该标准承诺,包含标题的所有翻译单元将看到变量的相同值,即使我们在运行时之前不知道它是什么.

它主要是一个图书馆作家工具.假设您的库只是标题.那么在过去的日子里,如果你需要一个像这样定义的静态常量,你有什么选择?

好吧,您可以在库中附带一个目标文件.它将从仅包含常量定义的翻译单元编译.现在该库不仅仅是标题库.

或者你可以依靠内联函数.内联变量效果可以通过以下方式实现:

class MyClass {
    static inline int mySecondVar();
};

inline int MyClass::mySecondVar() {
  static const int value = rand();
  return value;
}
Run Code Online (Sandbox Code Playgroud)

但它隐藏在语法墙后面,并使用函数调用运算符掩盖本质上是常量的东西.

  • ...特别是,为什么所描述的修改_“‘constexpr’说明符意味着变量和函数的‘内联’”_来自[P0386R0](http://open-std.org/JTC1/SC22/WG21/docs /papers/2016/p0386r0.pdf),指定应用于 (7.1.5p1) 作为 _“使用 constexpr 说明符**声明的函数**或变量隐式是`内联`函数或变量...”_ ,最终仅限于静态数据成员变量的子集;[dcl.constexpr]/1:_“使用 constexpr 说明符**声明的函数或**静态数据成员隐式是内联函数或变量...”_。 (2认同)