此问题是C++17: still using enums as constants?的后续问题。
旧版常量有几种形式,尤其是:
#define CONSTANT x
enum { CONSTANT = x };
const /*int/unsigned/whatever*/ CONSTANT = x;
关于static constexpr
和inline constexpr
常量作为替代的评论使我开始思考更新许多旧式常量(尤其是#define
常量)的问题。
据我所知,inline constexpr
值基本上只是被替换到位,就像内联函数一样(事实证明我是错的)。相反,static constexpr
值作为二进制文件的一部分存储在单独的区域中。假设我理解正确,什么时候应该优先选择另一个?我的直觉是,对于整数常量,inline constexpr
通常是首选。
答案 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";
这是允许此操作的唯一选项。