考虑这个示例代码:
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>();
struct Bar
: Foo<Bar>
{
static char const get_dummy() { return 42; }
};
( Also on Ideone .)
我希望 dummy
会在 Foo
的具体实例化后立即被初始化,而我在 Bar
中就有。 This question (以及最后的标准报价)解释得很清楚,为什么没有发生。
[...] in particular, the initialization (and any associated side-effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist.
有没有办法强制dummy
被初始化(有效地调用register_
)没有任何实例Bar
或 Foo
(没有实例,所以没有构造函数技巧)并且没有 Foo
的用户需要以某种方式显式声明成员?不需要派生类做任何事情的额外 cookie。
编辑:Found a way对派生类的影响最小:
struct Bar
: Foo<Bar>
{ // vvvvvvvvvvvv
static char const get_dummy() { (void)dummy; return 42; }
};
不过,我仍然希望派生类不必这样做。 :|
最佳答案
考虑:
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;
也可以不引入任何成员:
template<typename T, T> struct var { enum { value }; };
typedef char user;
template<typename T>
struct HasStatics {
static int a; // we force this to be initialized
static int b; // and this
// hope you like the syntax!
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;
关于c++ - 如何强制初始化静态成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6420985/