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

What's the difference between static constexpr and static inline variables in C++17?

用C++ 17得到内联变量。

它们的一个用途是在类中定义常量字段。

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

1
2
3
4
class MyClass {
    static constexpr int myFirstVar = 10;
    static const inline int mySecondVar = 100;
};

当然,constexpr使myFirstVar隐式内联。

在这里,使用constexprinline更好的选择是什么?

注:当你不需要警察的时候,那么inline就更容易了。用constexpr你没有选择。


您不必在声明点为mySecondVar指定初始值设定项。初始值设定项也不需要是constexpr本身。

这意味着,如果我们试图这样定义myFirstVar

1
2
3
4
5
class MyClass {
    static constexpr int myFirstVar;
};

int MyClass::myFirstVar = 1;

或者像这样:

1
2
3
4
5
#include <cstdlib>

class MyClass {
    static constexpr int myFirstVar = rand();
};

这两种方法都是不正确的。constexpr语义有充分的理由要求它。

inline说明符方法允许我们在头本身中包含静态变量定义,而初始值设定项不是constexpr;或者如果初始值设定项相当复杂,则不必在类定义本身中。

这是C++ 17中一个非常有效的标头:

1
2
3
4
5
6
7
#include <cstdlib>

class MyClass {
    static const int mySecondVar;
};

inline const int MyClass::mySecondVar = rand();

该标准向我们保证,包括头部的所有翻译单元都将看到相同的变量值,即使在运行时之前我们不知道它是什么。

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

好吧,您可以在库中附带一个对象文件。它将从只包含常量定义的翻译单元进行编译。现在,库不仅仅是头。

或者您可以改为依赖内联函数。内联变量效果可以通过以下方式实现:

1
2
3
4
5
6
7
8
class MyClass {
    static inline int mySecondVar();
};

inline int MyClass::mySecondVar() {
  static const int value = rand();
  return value;
}

但它隐藏在语法墙的后面,并用一个函数调用操作符屏蔽了本质上是常量的内容。