首頁  >  文章  >  後端開發  >  如何使用巢狀輔助結構可靠地初始化模板化 C 類別中的靜態成員?

如何使用巢狀輔助結構可靠地初始化模板化 C 類別中的靜態成員?

Barbara Streisand
Barbara Streisand原創
2024-10-30 05:43:02951瀏覽

 How can you reliably initialize static members in templated C   classes using nested helper structs?

模板類別和初始化器幫助程式中的靜態成員初始化

在 C 中,可以使用巢狀幫助程式結構來初始化靜態成員。雖然這種方法適用於非模板化類,但它可能會給具有模板參數的類別帶來挑戰。

問題陳述

考慮以下範例,其中在範本類別:

<code class="cpp">struct A
{
    struct InitHelper
    {
        InitHelper() { A::mA = "Hello, I'm A."; }
    };
    static std::string mA;
    static InitHelper mInit;

    static const std::string& getA() { return mA; }
};

template<class T>
struct B
{
    struct InitHelper
    {
        InitHelper() { B<T>::mB = "Hello, I'm B."; } // [3]
    };
    static std::string mB;
    static InitHelper mInit; // [4]

    static const std::string& getB() { return mB; }
    static InitHelper& getHelper() { return mInit; }
};</code>

在這種情況下,進行以下觀察:

  • 註解掉[1] 和[2] 後,輸出如預期:"A = Hello, I'm A."。
  • [1] 未註釋時,輸出為“A = Hello, I'm A.nB =”,而不是預期的“Hello, I'm B. ".
  • [ 1] 和[2] 均未註釋,輸出如預期:「A = 你好,我是A.nB = 你好,我是B。」。
  • 註解掉[1]並且取消註解[2],程式在[3]處出現段錯誤。

解釋

意外的行為源自於靜態成員初始化的行為模板化的類別。根據 ISO/IEC C 2003 標準 (14.7.1),只有當靜態資料成員本身以需要其定義存在的方式使用時,才會發生靜態資料成員的初始化。

  • 對於 A,靜態資料成員 mA 在 main 中明確引用,因此它的初始化發生在 main 函數執行之前。
  • 對於 B,存取 B::getB()引用 B::mB,觸發其初始化。然而,存取 B::getHelper() 並未直接使用 B::mInit,僅傳回初始化器助手的別名。

解決方案

至為了避免依賴隱式初始化並確保一致的初始化順序,建議在類別模板中明確特化靜態資料成員。在這種情況下:

<code class="cpp">template<>
std::string B<int>::mB = "Hello, I'm B (int specialization).";</code>

透過為模板類別的每個實例明確專門化靜態資料成員,可以明確觸發初始化並實現所需的行為,而無需求助於存取初始化程序助手。

以上是如何使用巢狀輔助結構可靠地初始化模板化 C 類別中的靜態成員?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn