簡體   English   中英

C++17 內聯變量 vs 內聯 static 變量

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

我對C++17引入的inline variable有點困惑。內inline variableinline static variable有什么區別? 這也會受到 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;
}

任何解釋將不勝感激!

在命名空間 scope:

inline static似乎只相當於static

inline變量僅在您在多個翻譯單元中定義相同變量時才有效。 由於static將變量限制為單個 TU,因此您不能有多個定義。

在 class scope:

inline只能出現在static變量上。

它具有正常的效果,允許您直接在 header 中初始化變量。要么:

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

或者:

struct A
{
    static int a;
};

inline int A::a = 42;

在 function scope:

不允許inline

對我來說,當它是數據成員時會變得更有趣。 C++17您可以將靜態數據成員聲明為inline 優點是您不必在source file為它們分配空間。 例如:

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

所以int A::b; 可以從源文件中刪除。

inline僅適用於具有靜態存儲持續時間的變量。

示例中的所有變量都具有命名空間作用域 ,為它們提供靜態存儲持續時間。 如果它們是inline則將它們聲明為static沒有凈效應。

如果聲明為static ,則classstructunion內的變量僅具有靜態存儲持續時間。 如果它們是inline那些變量必須是static

關於內聯變量以及我們為什么要使用它們的很好的答案可以在這里找到。 簡而言之,內聯變量允許對一個變量進行多個定義(甚至跨多個文件),這將導致 memory 中的一個變量。這允許 header 文件中的 constexpr 全局變量。

header.h

namespace constants
{
    inline constexpr double P = 1.11;
}

當定義具有不同的值時,行為是未定義的,但是當定義的乘法僅由於 header 文件而發生時,這應該不是問題。

其他人指出了類中的一個很好的應用程序:

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

然后你可以在任何地方引用這個變量,例如: C<int>::c;

inline static variable可以在 class 定義中定義,並且可以指定一個初始化程序 它不需要類外定義:

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

內聯變量消除了將 C++ 代碼打包為僅標頭庫的主要障礙。

如果需要聲明編譯單元之間共享的全局變量,在header文件中聲明為inline variables

這也會受到 scope 的影響嗎?

在命名空間 scope 中聲明的以下任何名稱都具有外部鏈接,並且在沒有命名空間的情況下聲明的用於外部鏈接的名稱(包括在多個源文件中)必須是內聯的。

請參閱此示例

鏈接包含有關內聯變量的寶貴信息。

定義來自 c++ 參考:引用: https://en.cppreference.com/w/cpp/language/inline

內聯變量定義為 inline static 關鍵字。 因此 inline static vartype yourvariablename // 是一個內聯變量。

關於內聯的有趣說明“完全在類/結構/聯合定義內定義的 function,無論它是成員 function 還是非成員朋友 function,如果它附加到全局模塊,則隱含地是內聯 function”(C++ 20)

好的,根據個人經驗,這就是為什么內聯 static 是一件非常非常重要的事情:

  1. 如果您需要做的只是在 C++ 文件中初始化一個 static 變量,那么您可以刪除 C++ 文件並使用內聯 static 初始化(但您的代碼將需要 C++ 17 及更高版本)

  2. 在 C++ 17 類名模板之前初始化 static 變量過於冗長。 你將不得不做類似的事情:

模板 class 類名 { static yourtype yourstaticvariable = yourvalue; // 你必須初始化它
};

template yourtype classname::yourstaticvariable = yourvalue;

或者使用內聯 static 你可以這樣做:

template <class T>
class classname
{
    static yourtype yourstaticvariable = yourvalue; // initialized
}
  1. 如果你使用內聯 static 來初始化常見的東西,你可以大量利用模板。 例如考慮 singleton,其中內聯 static 變量非常適合跟蹤實例,因此可以在一個文件中完成,而在初始化 static 變量之前會很痛苦。 當您擁有多變量模板時,這一點會變得更加明顯。
  2. 如果你利用內聯 static 來獲取單個 C++ header,你需要更少的包含文件和更少的 lib 項目。這可以大大減少大項目中的文件。

但是內聯 static 有一些注意事項:

  1. 您需要 C++ 17 歲及以上
  2. 你必須注意將初始化放在 ah 文件中的問題(如果你使用內聯靜態初始化,你可能想要這樣做)。 雖然這不一定是內聯 static 問題,但是如果您不注意包含的順序,可能將所有內容移動到 header 的決定可能會導致命名空間沖突、重用宏或其他問題。

但總的來說,這是一個很棒的功能。 如有疑問,請使用內聯 static 進行初始化並中斷我需要一個 c++ 文件來初始化 static 變量模式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM