ホームページ >バックエンド開発 >C++ >テンプレート化されたクラスでの静的メンバーの初期化の動作が異なるのはなぜですか?

テンプレート化されたクラスでの静的メンバーの初期化の動作が異なるのはなぜですか?

DDD
DDDオリジナル
2024-10-28 08:57:02728ブラウズ

 Why Does Static Member Initialization in Templated Classes Behave Differently?

テンプレート化されたクラスにおける静的メンバーの初期化の複雑さ

C での静的メンバーの初期化は広く使用されている手法ですが、次のような処理を行うと複雑になる可能性があります。テンプレート化されたクラス。テンプレート化されていないクラスでは、ネストされたヘルパー構造体を初期化に使用できますが、囲んでいるクラスがテンプレート化されている場合、このアプローチは不十分です。

次の単純化された例を考えてみましょう:

<code class="cpp">struct 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
{
    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;

int main()
{
    std::cout << "A = " << A::getA() << std::endl;

    // Comment/uncomment lines to observe different behaviors
    // std::cout << "B = " << B<int>::getB() << std::endl; // [1]
    // B<int>::getHelper(); // [2]
}</code>

期待される動作:

[1] がコメント化されておらず、[2] がコメント化されている場合、B::mB が「Hello, I'm B」に初期化されることが期待されます。 。ただし、これは発生しません。

実際の動作:

  • [1] と [2] のコメント付き: 副作用なし
  • [1] のコメントが解除されている場合: B::getB() は空の文字列を返します。
  • [1] および [2 ] コメントなし: B::mB は正しく初期化されています。
  • [1] がコメント化され、[2] がコメント化されていません: 静的初期化中にセグメンテーション違反が発生します。

不一致の理由:

ISO/IEC C 2003 標準によれば、テンプレート メンバーは、その定義が必要なコンテキストで参照されると暗黙的にインスタンス化されます。存在する。ただし、静的データ メンバーの初期化 (および関連する副作用) は、静的データ メンバーが明示的に使用される場合にのみ発生します。これは、テンプレート メンバーがインスタンス化されていないテンプレート、または完全なインスタンス化を必要としない他のコンテキストでのみ参照される場合、その静的データ メンバーは初期化されないことを意味します。

この例では、B:: getB() は B::mB が存在することを必要としますが、これはメンバ テンプレート宣言のインスタンス化を強制するだけであり、その定義 (イニシャライザを含む) ではありません。対照的に、B::getHelper() は B::mInit への参照を返すため、その定義が必要です。

解決策:

標準では、明示的に特殊化されたクラス テンプレートの静的データ メンバーの定義は順序付けされた初期化が行われる一方、他のクラス テンプレートの静的データ メンバーは順序付けされていない初期化が行われることが規定されています。一貫した初期化順序を確保するには、明示的な特殊化を使用する必要があります。

以上がテンプレート化されたクラスでの静的メンバーの初期化の動作が異なるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。