C++ 内联变量如何工作?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38043442/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do inline variables work?
提问by jotik
At the 2016 Oulu ISO C++ Standards meeting, a proposal called Inline Variableswas voted into C++17 by the standards committee.
在 2016 年奥卢 ISO C++ 标准会议上,一项名为内联变量的提案被标准委员会投票通过了 C++17。
In layman's terms, what are inline variables, how do they work and what are they useful for? How should inline variables be declared, defined and used?
通俗地说,什么是内联变量,它们如何工作以及它们有什么用?内联变量应该如何声明、定义和使用?
采纳答案by Cheers and hth. - Alf
The first sentence of the proposal:
提案的第一句话:
”The??
inline
specifier?can?be?applied?to?variables?as?well?as?to?functions.
”的?
inline
说明符?可以?可以?应用?到?变量?以及?作为?到?功能。
The 1guaranteed effect of inline
as applied to a function, is to allow the function to be defined identically, with external linkage, in multiple translation units. For the in-practice that means defining the function in a header, that can be included in multiple translation units. The proposal extends this possibility to variables.
1guaranteed effect inline
as 应用于函数,是允许在多个翻译单元中通过外部链接相同地定义函数。在实践中,这意味着在标题中定义函数,可以包含在多个翻译单元中。该提案将这种可能性扩展到变量。
So, in practical terms the (now accepted) proposal allows you to use the inline
keyword to define an external linkage const
namespace scope variable, or any static
class data member, in a header file, so that the multiple definitions that result when that header is included in multiple translation units are OK with the linker – it just chooses oneof them.
因此,实际上,(现已接受的)提案允许您使用inline
关键字在头文件中定义外部链接const
命名空间范围变量或任何static
类数据成员,以便在包含该头文件时产生多个定义链接器可以使用多个翻译单元——它只是选择其中一个。
Up until and including C++14 the internal machinery for this has been there, in order to support static
variables in class templates, but there was no convenient way to use that machinery. One had to resort to tricks like
直到并包括 C++14,内部机制一直存在,以支持static
类模板中的变量,但没有方便的方法来使用该机制。人们不得不求助于像
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`.
From C++17 and onwards I believe one can write just
从 C++17 开始,我相信人们可以只写
struct Kath
{
static std::string const hi;
};
inline std::string const Kath::hi = "Zzzzz..."; // Simpler!
… in a header file.
...在头文件中。
The proposal includes the wording
该提案包括措辞
”?An inline static data member can be defined in the class definition and may s??pecify a ?brace--or--equal--initializer. If the member is declared with the
constexpr
specifier, it may be redeclared in namespace scope with no initializer (this usage is deprecated? see?? D.X). Declarations of other static data members shall not specify a ?brace--or--equal--in??itializer
” ?内联静态数据成员可以在类定义来定义,并且可以S 13 pecify一支柱-或-相等-初始化程序。如果成员是用说明
constexpr
符声明的,它可能会在没有初始化程序的命名空间范围内重新声明(这种用法已被弃用?见??DX)。其他静态数据成员的声明不应指定 ?brace--or--equal--in??italizer
… which allows the above to be further simplified to just
……这使得上述内容可以进一步简化为
struct Kath
{
static inline std::string const hi = "Zzzzz..."; // Simplest!
};
… as noted by T.C in a commentto this answer.
Also, the??constexpr
??specifier?implies? inline
?for?static data members as?well?as?functions.
还有,? ?constexpr
??说明符?暗示?inline
?for?static 数据成员以及?as?functions。
Notes:
1 For a function inline
also has a hinting effect about optimization, that the compiler should prefer to replace calls of this function with direct substitution of the function's machine code. This hinting can be ignored.
注意:
1 对于一个函数inline
也有一个优化的暗示作用,编译器应该更喜欢用函数的机器码的直接替换来替换这个函数的调用。这个提示可以忽略。
回答by Philipp Cla?en
Inline variables are very similar to inline functions. It signals the linker that only one instance of the variable should exist, even if the variable is seen in multiple compilation units. The linker needs to ensure that no more copies are created.
内联变量与内联函数非常相似。它向链接器发出信号,该变量应该只存在一个实例,即使该变量在多个编译单元中可见。链接器需要确保不再创建副本。
Inline variables can be used to define globals in header only libraries. Before C++17, they had to use workarounds (inline functions or template hacks).
内联变量可用于在仅标头库中定义全局变量。在 C++17 之前,他们不得不使用变通方法(内联函数或模板技巧)。
For instance, one workaround is to use the Meyer's singletonwith an inline function:
例如,一种解决方法是将Meyer 的单例与内联函数一起使用:
inline T& instance()
{
static T global;
return global;
}
There are some drawbacks with this approach, mostly in terms of performance. This overhead could be avoided by template solutions, but it is easy to get them wrong.
这种方法有一些缺点,主要是在性能方面。模板解决方案可以避免这种开销,但很容易出错。
With inline variables, you can directly declare it (without getting a multiple definition linker error):
使用内联变量,您可以直接声明它(不会出现多定义链接器错误):
inline T global;
Apart from header only libraries, there other cases where inline variables can help. Nir Friedman covers this topic in his talk at CppCon: What C++ developers should know about globals (and the linker). The part about inline variables and the workarounds starts at 18m9s.
除了头文件库之外,还有其他情况下内联变量可以提供帮助。Nir Friedman 在他在 CppCon 的演讲中讨论了这个话题:C++ 开发人员应该了解全局变量(和链接器)。关于内联变量和解决方法的部分从 18m9s 开始。
Long story short, if you need to declare global variables that are shared between compilation units, declaring them as inline variables in the header file is straightforward and avoids the problems with pre-C++17 workarounds.
长话短说,如果您需要声明在编译单元之间共享的全局变量,在头文件中将它们声明为内联变量很简单,并且可以避免 C++17 之前的解决方法的问题。
(There are still use cases for the Meyer's singleton, for instance, if you explicitely want to have lazy initialization.)
(例如,如果您明确想要延迟初始化,仍然有 Meyer 单例的用例。)