首頁  >  文章  >  後端開發  >  如何在 C 中的巢狀模板函數中初始化靜態成員?

如何在 C 中的巢狀模板函數中初始化靜態成員?

Barbara Streisand
Barbara Streisand原創
2024-11-01 16:47:02801瀏覽

 How to Initialize Static Members in Nested Template Functions in C  ?

巢狀範本函數中的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; }
};
std::string A::mA;
A::InitHelper A::mInit;


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

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

使用g 4.4.1 編譯時,會出現以下幾個觀察結果:

  • 將[1] 和[2] 註解掉,A = 你好,我是A。 這個表示初始化如預期進行。
  • [1] 未註釋,A = Hello, I'm A. B = 這表示 B::mB 的初始化未觸發自動。
  • [1] 和 [2] 均未註釋,A = 你好,我是 A。 B = 你好,我是 B。 這確認了對 B 的存取: :mInit(透過[2])發起B::mB的初始化。
  • 註解掉[1]並且取消註解[2],會發生段錯誤,這表示透過直接存取helper 本身,過早嘗試初始化B::mB,從而導致錯誤。

此行為源自於編譯器對 ISO/IEC C 2003 標準 (14.7.1) 的解釋。標準規定:

「除非類別範本或成員範本的成員已被明確實例化或明確特化,否則當在類別範本中引用特化時,會隱式實例化此成員的特化。 p>

這解釋了為什麼在給定的範例中,靜態成員在透過getB() 或getHelper() 方法存取之前不會被初始化。在主函數中明確實例化類別模板或成員模板將強制它們在此時初始化。然而,對於直接存取不可行的場景,該標準沒有指定一種優雅的解決方法來初始化巢狀模板函數中的靜態成員。

以上是如何在 C 中的巢狀模板函數中初始化靜態成員?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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