内联variables如何工作?

在2016年奥卢ISO C ++标准会议上,标准委员会将一项名为Inline Variables的提案投票给了C ++ 17。

通俗地说,什么是内联variables,它们是如何工作的,它们对于什么有用? 内联variables应该如何声明,定义和使用?

提案的第一句话:

inline说明符可以应用于variables以及函数。

inline应用于函数的保证效果是允许在多个翻译单元中使用外部链接对函数进行相同的定义。 在实践中,这意味着在一个标题中定义函数,这可以包含在多个翻译单元中。 该提议将这种可能性扩展到variables。

所以,实际上,(现在接受的)提议允许你使用inline关键字来在头文件中定义一个外部链接const命名空间范围variables,或者任何static类数据成员,以便当这个头文件被包含在多个翻译单元中,链接器是可以的 – 它只是select其中的一个。

直到包括C ++ 14在内,为了支持类模板中的staticvariables,内部机器已经存在,但是没有方便的方法来使用这个机器。 一个人不得不求助于像

 template< class Dummy > struct Kath_ { static std::string const hi; }; template< class Dummy > std::string const Kath_<Dummy>::hi = "Zzzzz..."; using Kath = Kath_<void>; // Allows you to write `Kath::hi`. 

从C ++ 17开始,我相信一个人可以写

 struct Kath { static std::string const hi; }; inline std::string const Kath::hi = "Zzzzz..."; // Simpler! 

…在头文件中。

提案包括措辞

内联的静态数据成员可以在类定义中定义,并且可以使用括号或等于初始值设定项。 如果成员是用constexpr说明符声明的,它可以在没有初始化的情况下在命名空间范围内重新声明(这个用法是不推荐的,参见DX)。 其他静态数据成员的声明不得在itializer中指定括号或等号

…这可以使上述进一步简化

 struct Kath { static inline std::string const hi = "Zzzzz..."; // Simplest! }; 

……正如TC在评论这个答案时所指出的那样。

而且, ​constexpr说明符暗含了静态数据成员以及函数的inline


笔记:
¹对于inline函数也有一个关于优化的暗示效果,编译器应该优先使用函数的机器代码直接replace此函数的调用。 这个暗示可以忽略。