Como forçar um membro estático a ser inicializado?

Considere este código de exemplo:

template char register_(){ return D::get_dummy(); // static function } template struct Foo{ static char const dummy; }; template char const Foo::dummy = register_(); struct Bar : Foo { static char const get_dummy() { return 42; } }; 

( Também no Ideone .)

Eu esperaria que o dummy fosse inicializado assim que houvesse uma instanciação concreta do Foo , o que eu tenho com o Bar . Esta pergunta (e a citação padrão no final) explicou bem claro, porque isso não está acontecendo.

[…] em particular, a boot (e quaisquer efeitos colaterais associados) de um membro de dados estáticos não ocorre, a menos que o membro de dados estáticos seja usado de forma que exija a definição do membro de dados estáticos.

Existe alguma maneira de forçar o dummy a ser inicializado (efetivamente chamando register_ ) sem qualquer instância de Bar ou Foo (sem instâncias, portanto sem truques de construtor) e sem que o usuário de Foo precise declarar explicitamente o membro de alguma forma? Cookies extras para não precisar que a class derivada faça nada.


Editar : encontrou uma maneira com impacto mínimo na class derivada:

 struct Bar : Foo { // vvvvvvvvvvvv static char const get_dummy() { (void)dummy; return 42; } }; 

No entanto, eu ainda gostaria que a class derivada não tivesse que fazer isso. : |

Considerar:

 template struct value { }; template struct HasStatics { static int a; // we force this to be initialized typedef value value_user; }; template int HasStatics::a = /* whatever side-effect you want */ 0; 

Também é possível sem introduzir nenhum membro:

 template struct var { enum { value }; }; typedef char user; template struct HasStatics { static int a; // we force this to be initialized static int b; // and this // hope you like the syntax! user :var::value, :var::value; }; template int HasStatics::a = /* whatever side-effect you want */ 0; template int HasStatics::b = /* whatever side-effect you want */ 0; 

Existe alguma maneira de forçar o dummy a ser inicializado (efetivamente chamando register_) sem qualquer instância de Bar ou Foo (sem instâncias, então nenhum truque de construtor)?

Isso não seria suficiente?

 std::cout << Foo::dummy; 

Algo assim vem à minha mente:

 // in some c++ file (to make i with internal linkage) static int i = init_dummy(Foo::dummy); 

onde init_dummy é definido assim:

 int init_dummy(...) { return 1; } 

Devido a variável args você pode colocar mais inicializações lá como:

 static int i = init_dummy(Foo::dummy, Foo::dummy, Foo::dummy); 

Como você está verificando o valor definido pelo Bar. Eu mudei seu código e adicionei outra function na barra como:

 .... static char const get_dummy(int){return Foo::dummy;} .... 

e está me dando exatamente o resultado esperado. Eu posso não estar entendendo corretamente, o que você quer exatamente alcançar?

Os membros estáticos são compartilhados entre os objects, portanto, seu escopo deve ser resolvido no access. é por isso que usamos :: explicando explicitamente ao compilador que este é o membro da class que queremos acessar.

    Intereting Posts