简体   繁体   English

C++17 内联变量 vs 内联 static 变量

[英]C++17 inline variable vs inline static variable

I am a bit confused by the inline variable introduced by C++17. What are the differences between inline variable and inline static variable ?我对C++17引入的inline variable有点困惑。内inline variableinline static variable有什么区别? Also will this be affected by scope?这也会受到 scope 的影响吗?

inline T var_no_scope;
inline static T static_var_no_scope;

namespace scope {
  inline T var_scope;
  inline static T static_var_scope;
}

Any explanation will be appreciated!任何解释将不胜感激!

At namespace scope:在命名空间 scope:

inline static seems to be equivalent to just static . inline static似乎只相当于static

inline on variables only has effect when you define the same variable in several translation units. inline变量仅在您在多个翻译单元中定义相同变量时才有效。 Since static restricts the variable to a single TU, you can't have more than one definition.由于static将变量限制为单个 TU,因此您不能有多个定义。

At class scope:在 class scope:

inline can only appear on static variables. inline只能出现在static变量上。

It has its normal effect, allowing you to initialize the variable directly in the header. Either:它具有正常的效果,允许您直接在 header 中初始化变量。要么:

struct A
{
    inline static int a = 42;
};

Or:或者:

struct A
{
    static int a;
};

inline int A::a = 42;

At function scope:在 function scope:

inline is not allowed.不允许inline

For me it becomes more interesting when it is a data members. 对我来说,当它是数据成员时会变得更有趣。 In C++17 you can declare your static data members as inline . C++17您可以将静态数据成员声明为inline The advantage is that you don't have to allocate space for them in a source file . 优点是您不必在source file为它们分配空间。 For example: 例如:

class A
{
// Omitted for brevity
static inline int b = 0;
};

So int A::b; 所以int A::b; can be removed from the source file. 可以从源文件中删除。

inline is applicable to variables only with static storage duration . inline仅适用于具有静态存储持续时间的变量。

All of the variables in your example have namespace scope , giving them static storage duration. 示例中的所有变量都具有命名空间作用域 ,为它们提供静态存储持续时间。 Declaring them static has no net effect if they are inline . 如果它们是inline则将它们声明为static没有净效应。

A variable inside a class , struct or union only has static storage duration if it is declared static . 如果声明为static ,则classstructunion内的变量仅具有静态存储持续时间。 Those varibles must be static if they are to be inline . 如果它们是inline那些变量必须是static

Great answer about inline variables and why we want to use them can be found here .关于内联变量以及我们为什么要使用它们的很好的答案可以在这里找到。 In short inline variable allows to have multiple definition of a variable (even across multiple files), that will result in one variable in memory. This allow constexpr global variables in header files.简而言之,内联变量允许对一个变量进行多个定义(甚至跨多个文件),这将导致 memory 中的一个变量。这允许 header 文件中的 constexpr 全局变量。

header.h

namespace constants
{
    inline constexpr double P = 1.11;
}

Behavior is undefined when definitions have different values, but this shouldn't be a problem when multiplication of definitions occur only due to header file.当定义具有不同的值时,行为是未定义的,但是当定义的乘法仅由于 header 文件而发生时,这应该不是问题。

Others have pointed to a nice application in classes:其他人指出了类中的一个很好的应用程序:

template<typename T>
struct C
{
    static inline constexpr int c = 10;
};

And then you can reference this variable anywhere, eg with: C<int>::c;然后你可以在任何地方引用这个变量,例如: C<int>::c;

The inline static variable can be defined in the class definition and may specify an initializer . inline static variable可以在 class 定义中定义,并且可以指定一个初始化程序 It does not need an out-of-class definition:它不需要类外定义:

struct X
{
    inline static int n = 1;
};

Inline variables eliminate the main obstacle to packaging C++ code as header-only libraries .内联变量消除了将 C++ 代码打包为仅标头库的主要障碍。

If you need to declare global variables that are shared between compilation units , declare them as inline variables in the header file.如果需要声明编译单元之间共享的全局变量,在header文件中声明为inline variables

Also will this be affected by scope?这也会受到 scope 的影响吗?

Any of the following names declared at namespace scope have external linkage and also names declared without a namespace for external linkage including in multiple source files must be inline .在命名空间 scope 中声明的以下任何名称都具有外部链接,并且在没有命名空间的情况下声明的用于外部链接的名称(包括在多个源文件中)必须是内联的。

See this Example .请参阅此示例

This link has valuable information about inline variables.链接包含有关内联变量的宝贵信息。

definition from c++ reference: citation: https://en.cppreference.com/w/cpp/language/inline定义来自 c++ 参考:引用: https://en.cppreference.com/w/cpp/language/inline

inline variable is defined as inline static keyword.内联变量定义为 inline static 关键字。 Hence inline static vartype yourvariablename // is a inline variable.因此 inline static vartype yourvariablename // 是一个内联变量。

Interesting note about inline "A function defined entirely inside a class/struct/union definition, whether it's a member function or a non-member friend function, is implicitly an inline function if it is attached to the global module"(C++ 20)关于内联的有趣说明“完全在类/结构/联合定义内定义的 function,无论它是成员 function 还是非成员朋友 function,如果它附加到全局模块,则隐含地是内联 function”(C++ 20)

Ok from personal experience here's why inline static is a really really big thing:好的,根据个人经验,这就是为什么内联 static 是一件非常非常重要的事情:

  1. If all you need todo is initialize a static variable in a C++ file then you can remove the C++ file and use inline static initialization(but your code will require C++ 17 and up)如果您需要做的只是在 C++ 文件中初始化一个 static 变量,那么您可以删除 C++ 文件并使用内联 static 初始化(但您的代码将需要 C++ 17 及更高版本)

  2. Initializing static variables in pre C++ 17 classname templates is just overly verbose.在 C++ 17 类名模板之前初始化 static 变量过于冗长。 You would have to do something like:你将不得不做类似的事情:

template class classname { static yourtype yourstaticvariable = yourvalue;模板 class 类名 { static yourtype yourstaticvariable = yourvalue; // and you'll have to initialize it // 你必须初始化它
}; };

template yourtype classname::yourstaticvariable = yourvalue; template yourtype classname::yourstaticvariable = yourvalue;

OR with inline static you can just do:或者使用内联 static 你可以这样做:

template <class T>
class classname
{
    static yourtype yourstaticvariable = yourvalue; // initialized
}
  1. You can heavily exploit templates if you use inline static for initializing common things.如果你使用内联 static 来初始化常见的东西,你可以大量利用模板。 Consider for instance the singleton where a inline static variable is perfect for tracking the instance and hence can be done in one file where before initializing the static variable would be painful.例如考虑 singleton,其中内联 static 变量非常适合跟踪实例,因此可以在一个文件中完成,而在初始化 static 变量之前会很痛苦。 This becomes even more evident when you have multivariable templates.当您拥有多变量模板时,这一点会变得更加明显。
  2. You need less C++ include files and less lib projects if you exploit inline static for single C++ header. This can heavily trim down files in a big project.如果你利用内联 static 来获取单个 C++ header,你需要更少的包含文件和更少的 lib 项目。这可以大大减少大项目中的文件。

But there some caveats with inline static:但是内联 static 有一些注意事项:

  1. You need C++ 17 and up您需要 C++ 17 岁及以上
  2. You have to pay attention to issues of putting your initialization in ah file(which you probably want to do if you initialize with inline static).你必须注意将初始化放在 ah 文件中的问题(如果你使用内联静态初始化,你可能想要这样做)。 Although this isn't necessarily a inline static issue but the decision to potentially moving everything to a header could lead to possible issues like namespace collisions, reusing macros or other things if you not careful with your order of inclusion.虽然这不一定是内联 static 问题,但是如果您不注意包含的顺序,可能将所有内容移动到 header 的决定可能会导致命名空间冲突、重用宏或其他问题。

But overall it's a fantastic feature.但总的来说,这是一个很棒的功能。 When in doubt initialize with inline static and break the I need a c++ file to initialize a static variable pattern.如有疑问,请使用内联 static 进行初始化并中断我需要一个 c++ 文件来初始化 static 变量模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 C++17 中初始化后可以更改内联变量吗? - Can an inline variable be changed after initialization in C++17? 全局 static 内联变量,可能跨翻译单元重新定义 class - 这种特殊情况是 C++17 中的未定义行为吗? - Global static inline variable with potential class redefinition across translation units - Is this particular case undefined behavior in C++17? C ++ 17静态内联成员的编译器错误 - Compiler error with C++17 static inline members 为什么C ++ 17中的全局内联变量和静态内联成员需要保护? - Why do global inline variables and static inline members in C++17 need guards? c ++ 17:仅标题:类静态变量错误 - c++17: header only: class static variable errors C++17 中的静态 constexpr 和静态内联变量有什么区别? - What's the difference between static constexpr and static inline variables in C++17? 内联静态常量与静态常量变量 - Inline static const vs static const variable 在Visual Studio中使用C ++ 17静态内联成员时出现奇怪的行为 - Strange behaviour when using C++17 static inline members in Visual Studio class模板中static内联成员变量的初始化顺序(C++17) - Initialization order of static inline member variables in class templates (C++17) c ++ 17内联+ thread_local vs thread_local - c++17 inline + thread_local vs thread_local
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM