【发布时间】:2011-09-19 05:50:31
【问题描述】:
考虑这个示例代码:
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; }
};
我希望dummy 会在Foo 的具体实例化后立即被初始化,我在Bar 中拥有该实例化。 This question(以及最后的标准报价)解释得很清楚,为什么没有发生。
[...] 特别是,静态数据成员的初始化(以及任何相关的副作用)不会发生,除非静态数据成员本身以需要定义静态数据成员的方式使用存在。
有什么方法可以强制初始化dummy(有效地调用register_)没有Bar或Foo的任何实例(没有实例,所以没有构造函数技巧)并且没有Foo 的用户需要以某种方式显式声明成员?不需要派生类做任何事情的额外 cookie。
编辑:Found a way,对派生类的影响最小:
struct Bar
: Foo<Bar>
{ // vvvvvvvvvvvv
static char const get_dummy() { (void)dummy; return 42; }
};
不过,我仍然希望派生类不必这样做。 :|
【问题讨论】:
-
@Bo:当然可以,但是我想对派生类/外部世界隐藏这种用法,并且宁愿以某种方式将其放入
Foo本身。 :// -
@Serge:为什么不应该呢?
get_dummy中的dummy是未初始化的,当然,但这并不重要。 :) 我实际上并没有使用它。 -
@Xeo:“get_dummy 中的 dummy 是未初始化的,当然,但这没关系。:) 我实际上并没有使用它。”是的。但是为什么它应该强制
Foo<Bar>::dummy被初始化呢?还有什么应该阻止编译器优化语句(void)dummy;(没有效果)。 -
@Serge:它强制
dummy被初始化,因为它被使用,正如引用的那样。 w.r.t.优化,我得检查一下。 -
@Xeo:“它强制 dummy 被初始化,因为它已被使用”实际上并非如此。仅当您在某处致电
get_dummy()时才使用它。静态成员和全局变量在main的第一个语句之前或在第一次使用与该静态成员或全局变量在同一翻译单元中定义的任何对象或函数之前进行初始化。因此,如果您不使用来自实例化模板 Foo 特化的同一翻译单元的任何对象或函数,则完全允许不初始化 Foo::dummy。
标签: c++ templates static-members static-initialization