每周技巧 #168:`inline` 变量

本节阅读量:

本文翻译自 Abseil 官网的 Tip of the Week #168: inline Variables

原文最初作为 TotW #168 发布于 2019 年 9 月 12 日。

作者:James Dennett

更新于 2020 年 4 月 6 日。

快捷链接:abseil.io/tips/168

下面是在 C++17 中使用 inline 变量,在头文件里定义字符串常量的一种安全方式:

1
inline constexpr absl::string_view kHelloWorld = "Hello World.";

使用 constexpr 可以确保初始化和析构安全,而这里使用 inline 可以确保程序中只有一个 kHelloWorld 副本。

在这里使用关键字 inline 起初可能显得奇怪,尤其是如果你习惯把 inline 主要想成优化提示。头文件中函数使用 inline 是一个很接近的类比;把上面的变量定义和下面这样的东西比较:

1
2
3
inline constexpr absl::string_view HelloWorld() {
  return "Hello World.";
}

但变量版本的优势是,这个字符串保证每次都位于相同内存地址。

几乎每个在头文件中定义的全局变量都应该标记为 inline,并且通常也应该是 constexpr。如果没有标记为 inline,那么每个包含该头文件的 .cc 文件都会有一个独立变量实例,这可能导致微妙的 ODR(一处定义规则)违规。

在头文件之外,没有必要把变量标记为 inline

注意:从 C++17 开始,类的 static constexpr 数据成员隐式inline。这个特殊情况不会改变已有代码的语义,但意味着现在不再需要在源文件中为该成员提供单独定义。这适用于 static constexpr 数据成员,不适用于其他 constexpr 变量,也不适用于仅仅是 static const 的数据成员。

参考:

每周技巧 #166:当拷贝不是拷贝

上一节

每周技巧 #171:避免哨兵值

下一节


本节目录