Удивительно, как кусочки головоломки сочетаются друг с другом. Спасибо за подробное объяснение.
я есть какой-то устаревший код, и мне нужно добавить новый класс для сообщения (что не имеет отношения к моему вопросу). Но оказывается, что мне нужно объявить пустой конструктор для инициализации некоторой статики. Не конструктор по умолчанию или предоставленный компилятором, но пустой определяемый пользователем. Я попытался сократить код до MWE и вот что я получаю:
#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()
{
}
Вот что происходит:
Сама программа пуста, т.е. экземпляры не создаются.Есть CRTP дляA
класс, который, кажется, имеет решающее значение для примера.Есть статическая декларация для базыA
и я ожидаю, что его конструктор будет вызван.Есть фиктивный вызов функции, которая ничего не делает, но также критична.Проблема в том, что если я не предоставлю пользовательский конструктор, то статический конструктор никогда не будет вызван. И я не могу понять, зачем мне это? В чем разница с дефолтом или сгенерированным компилятором? И зачем мне вызывать фиктивную функцию?
Я считаю, что есть правило для этого. Я проверил это с разными версиями gcc и clang - поведение одинаковое. Я очень ценю ссылки на стандарт / документацию.