静的メンバーを強制的に初期化する方法
C で見落とされがちな動作は、静的メンバーが自動的に初期化されることが保証されていないことです。メンバは具象クラスの最初のインスタンス化で初期化されることが予想されるかもしれません。ただし、標準からの引用が示すように、これは静的メンバーが積極的に利用されている場合にのみ発生します:
"* 特に、静的データ メンバーの初期化 (および関連する副作用) は発生しません。静的データ メンバーの定義が存在する必要がある方法で静的データ メンバー自体が使用されている場合を除きます。
問題
次のコードを考えてみましょう。
<code class="cpp">template <class D> char register_() { return D::get_dummy(); // static function } template <class D> struct Foo { static char const dummy; }; template <class D> char const Foo<D>::dummy = register_<D>(); // static member initialized with `register_<D>()` struct Bar : Foo<Bar> { static char const get_dummy() { return 42; } };</code>
直感的には、Bar のインスタンス化時にダミーが初期化されることが期待されるかもしれません。しかし、これは起こりません。
質問
Bar または Foo のインスタンスを必要とせずにダミーの初期化を強制するにはどうすればよいでしょうか?さらに、このソリューションでは、Foo のユーザーによるメンバーの明示的な参照が必要であってはなりません。
考えられる解決策
解決策 1 (派生クラスへの影響を最小限に抑える)
Bar の get_dummy() メソッドに対する次の変更により、ダミーの初期化が強制されます:
<code class="cpp">static char const get_dummy() { (void)dummy; return 42; }</code>
解決策 2 (派生クラスへの変更なし)
このソリューションはテンプレート メタプログラミングを利用します:
<code class="cpp">template<typename T, T> struct value { }; template<typename T> struct HasStatics { static int a; // we force this to be initialized typedef value<int&, a> value_user; }; template<typename T> int HasStatics<T>::a = /* whatever side-effect you want */ 0;</code>
または、追加のメンバーを導入せずに実行することもできます:
<code class="cpp">template<typename T, T> struct var { enum { value }; }; template<typename T> struct HasStatics { static int a; // we force this to be initialized static int b; // and this char user :var<int&, a>::value, :var<int&, b>::value; }; template<typename T> int HasStatics<T>::a = /* whatever side-effect you want */ 0; template<typename T> int HasStatics<T>::b = /* whatever side-effect you want */ 0;</code>
以上が明示的な参照を行わずに C で静的メンバーの初期化を強制する方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。