如何强制静态成员初始化?
考虑这个示例代码:(
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; }
};
也在 Ideone 上。)
我希望 dummy
得到一旦有 Foo
的具体实例化,我就用 Bar
进行初始化。 这个问题(以及最后的标准引用)解释得很清楚,为什么这没有发生。
[...] 特别是,静态数据成员的初始化(以及任何相关的副作用)不会发生,除非静态数据成员本身的使用方式需要静态数据成员的定义存在。
有没有办法强制 dummy
初始化(有效调用register_
)没有任何实例Bar
或 Foo
(没有实例,因此没有构造函数欺骗)并且 Foo
的用户不需要以某种方式显式声明成员?不需要派生类做任何事情的额外cookie。
编辑:找到一种对派生类影响最小的方法:
struct Bar
: Foo<Bar>
{ // vvvvvvvvvvvv
static char const get_dummy() { (void)dummy; return 42; }
};
不过,我会仍然喜欢派生类不必这样做。 :|
Consider this example code:
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; }
};
I'd expect dummy
to get initialized as soon as there is a concrete instantiation of Foo
, which I have with Bar
. This question (and the standard quote at the end) explained pretty clear, why that's not happening.
[...] 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.
Is there any way to force dummy
to be initialized (effectively calling register_
) without any instance of Bar
or Foo
(no instances, so no constructor trickery) and without the user of Foo
needing to explicitly state the member in some way? Extra cookies for not needing the derived class to do anything.
Edit: Found a way with minimal impact on the derived class:
struct Bar
: Foo<Bar>
{ // vvvvvvvvvvvv
static char const get_dummy() { (void)dummy; return 42; }
};
Though, I'd still like the derived class not having to do that. :|
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
考虑一下:
不引入任何成员也是可能的:
Consider:
It's also possible without introducing any member:
我们可以使用一个基于必须用类实例化的声明的简单技巧:
请注意,某些编译器会警告与 null 的比较;可以使用
&foo==&foo
、(bool)&foo
或((void)&foo,true)< 来避免/code> 如果需要的话。
另请注意,GCC 9.0–9.2 不将此视为 odr-use< /a>.
We can use a simple trick based on a declaration that must be instantiated with the class:
Note that some compilers warn about the comparison to null; that can be avoided with
&foo==&foo
,(bool)&foo
, or((void)&foo,true)
if needed.Note also that GCC 9.0–9.2 don’t count this as an odr-use.
我想到了类似的事情:
init_dummy 的定义如下:
由于变量 args,您可以在那里放置更多初始化,例如:
Something like that comes to my mind:
where init_dummy is defined like this:
Due to variable args you can put more initializations there like:
我最近遇到了这个。官方解决方案是显式模板实例化,此处进行了描述。
在上述情况下,语句应如下所示:
I recently bumped into this. The official solution would be explicit template instantiation, described here.
In the above case, the statement should look like this:
这还不够吗?
Wouldn't this be sufficient?