如何强制初始化静态成员
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 实例化时初始化 dummy。然而,这种情况不会发生。
问题
如何在不需要 Bar 或 Foo 实例的情况下强制初始化 dummy?此外,该解决方案不应需要 Foo 的用户显式引用该成员。
潜在解决方案
解决方案 1(对派生类影响最小)
对 Bar 的 get_dummy() 方法进行以下修改将强制初始化 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中文网其他相关文章!