首页  >  文章  >  后端开发  >  如何使用嵌套辅助结构可靠地初始化模板化 C 类中的静态成员?

如何使用嵌套辅助结构可靠地初始化模板化 C 类中的静态成员?

Barbara Streisand
Barbara Streisand原创
2024-10-30 05:43:021046浏览

 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