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. :|
Wouldn't this be sufficient?
Consider:
It's also possible without introducing any member:
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:
How are you checking the value set by Bar. I changed your code and added another function in bar as:
and it is giving me exactly the expected result. I may not be understanding correctly, what do you exactly want to achieve ?
Static members are shared among the objects so their scope must be resolved at access. that is why we use :: by telling compiler explicitly that this is the member of the class we want to access.