Quais são as regras para uma inicialização de variável estática de classe?
Eu tenho algum código legado e preciso adicionar uma nova classe para a mensagem (o que é irrelevante para a minha pergunta). Mas acontece que eu preciso declarar um construtor vazio para que alguma estática seja inicializada. Não é um construtor padrão ou fornecido pelo compilador, mas vazio definido pelo usuário. Eu tentei reduzir o código para MWE e aqui o que eu recebo:
#include <iostream>
using namespace std;
struct Test
{
Test() {cout << "Test::Test()" << "\n";}
void dummy(){}
};
template<typename T>
struct Message
{
Message()
{
test.dummy(); // this call have to be here in order to initialize Test, but why?
}
static Test test;
};
template<typename T>
Test Message<T>::test;
struct A : public Message<A>
{
//A(){} // uncomment this (and comment the default one) to call the Test constructor
A() = default;
};
int main()
{
}
Isto é o que está acontecendo:
O programa em si está vazio, ou seja, nenhuma instância é criada.Há um CRTP para umA
classe, que parece ser crítica para o exemplo.Há uma declaração estática para a base deA
e eu estou esperando que seu construtor seja chamado.Há uma chamada fictícia para a função que não faz nada, mas também é crítica.O problema é que, se eu não fornecer um construtor personalizado, o construtor estático nunca será chamado. E não consigo entender por que preciso disso? Qual é a diferença com o padrão ou o compilador gerado? E por que preciso chamar uma função fictícia?
Eu acredito que há uma regra para isso. Eu verifiquei com versões diferentes do gcc e clang - o comportamento é o mesmo. Aprecio muito os links para a norma / documentação.