替换常量:何时使用静态 constexpr 和内联 constexpr?
Replacing constants: when to use static constexpr and inline constexpr?
此问题是 的后续问题。
遗留常量有多种形式,特别是:
#define CONSTANT x
enum { CONSTANT = x };
const /*int/unsigned/whatever*/ CONSTANT = x;
关于 static constexpr
和 inline constexpr
常量作为替代品的评论让我开始思考更新我们许多遗留常量(特别是 #define
常量)的主题。
据我了解,inline constexpr
值基本上只是替换到位,就像一个内联函数(我已被证明是错误的)。相反,static constexpr
值作为二进制文件的一部分存储在单独的区域中。假设我理解正确,什么时候应该优先选择一个?我的直觉是,对于整数常量,inline constexpr
通常是首选。
在 C++17 中,在命名空间范围内的 headers 中替换那些旧习语(例如 #define
)的正确方法是使用 constexpr inline
变量——和 not static
(暗示:它们已经有内部链接)。
虽然通常您不会遇到 ODR 问题(因为您描述的整数 compile-time 常量很少 ODR-used 并且在 inline
中提供了它们的典型用法函数),最好将它们标记为 inline
,因为我们在语言中拥有该功能并避免所有问题。
有关它的技术细节,请参阅 Should `const` and `constexpr` variables in headers be `inline` to prevent ODR violations?。
C++17 中全局常量的首选应该是:
inline constexpr int CONSTANT = 42;
这为您提供了一个不错的第一个 class 变量,您可以在常量表达式中使用它,并且不会有 ODR 问题。大家可以参考一下。
宏会带来问题...成为宏。枚举仅限于整数类型。使用 constexpr
变量,您可以拥有任何文字类型。在 C++20 中,您很可能可以随心所欲地编写:
inline constexpr std::vector<int> small_primes = {2, 3, 5, 7, 11};
inline constexpr std::string cool_name = "Barry";
这是唯一允许这样做的选项。
此问题是
遗留常量有多种形式,特别是:
#define CONSTANT x
enum { CONSTANT = x };
const /*int/unsigned/whatever*/ CONSTANT = x;
关于 static constexpr
和 inline constexpr
常量作为替代品的评论让我开始思考更新我们许多遗留常量(特别是 #define
常量)的主题。
据我了解,inline constexpr
值基本上只是替换到位,就像一个内联函数(我已被证明是错误的)。相反,static constexpr
值作为二进制文件的一部分存储在单独的区域中。假设我理解正确,什么时候应该优先选择一个?我的直觉是,对于整数常量,inline constexpr
通常是首选。
在 C++17 中,在命名空间范围内的 headers 中替换那些旧习语(例如 #define
)的正确方法是使用 constexpr inline
变量——和 not static
(暗示:它们已经有内部链接)。
虽然通常您不会遇到 ODR 问题(因为您描述的整数 compile-time 常量很少 ODR-used 并且在 inline
中提供了它们的典型用法函数),最好将它们标记为 inline
,因为我们在语言中拥有该功能并避免所有问题。
有关它的技术细节,请参阅 Should `const` and `constexpr` variables in headers be `inline` to prevent ODR violations?。
C++17 中全局常量的首选应该是:
inline constexpr int CONSTANT = 42;
这为您提供了一个不错的第一个 class 变量,您可以在常量表达式中使用它,并且不会有 ODR 问题。大家可以参考一下。
宏会带来问题...成为宏。枚举仅限于整数类型。使用 constexpr
变量,您可以拥有任何文字类型。在 C++20 中,您很可能可以随心所欲地编写:
inline constexpr std::vector<int> small_primes = {2, 3, 5, 7, 11};
inline constexpr std::string cool_name = "Barry";
这是唯一允许这样做的选项。