替换常量:什么时候使用静态constexpr和内联constexpr?

时间:2019-01-31 17:56:27

标签: c++ constants c++17 constexpr

此问题是C++17: still using enums as constants?的后续问题。

旧版常量有几种形式,尤其是:

  • #define CONSTANT x
  • enum { CONSTANT = x };
  • const /*int/unsigned/whatever*/ CONSTANT = x;

关于static constexprinline constexpr常量作为替代的评论使我开始思考更新许多旧式常量(尤其是#define常量)的问题。

据我所知,inline constexpr值基本上只是被替换到位,就像内联函数一样(事实证明我是错的)。相反,static constexpr值作为二进制文件的一部分存储在单独的区域中。假设我理解正确,什么时候应该优先选择另一个?我的直觉是,对于整数常量,inline constexpr通常是首选。

2 个答案:

答案 0 :(得分:2)

在C ++ 17中,替换名称空间范围标头中的那些旧习惯用法(例如#define)的正确方法是使用constexpr inline变量-而 not static(这意味着:它们已经具有内部链接)。

虽然通常不会遇到ODR问题(因为您描述的整数编译时常量很少使用ODR,并且inline函数中提供了它们的典型用法的规定),但最好现在,我们将其标记为inline,并避免了所有问题。

有关其技术细节,请参见Should `const` and `constexpr` variables in headers be `inline` to prevent ODR violations?

答案 1 :(得分:2)

对于C ++ 17中的全局常量,您应该使用:

inline constexpr int CONSTANT = 42;

这为您提供了一个不错的,一流的变量,您可以在常量表达式中使用它,并且不会出现ODR问题。您可以引用它。

宏带来了...成为宏的问题。枚举仅限于整数类型。使用constexpr变量,可以使它们具有任何文字类型。在C ++ 20中,您很可能可以疯狂地编写:

inline constexpr std::vector<int> small_primes = {2, 3, 5, 7, 11};
inline constexpr std::string cool_name = "Barry";

这是允许此操作的唯一选项。