Удивительно, как кусочки головоломки сочетаются друг с другом. Спасибо за подробное объяснение.

я есть какой-то устаревший код, и мне нужно добавить новый класс для сообщения (что не имеет отношения к моему вопросу). Но оказывается, что мне нужно объявить пустой конструктор для инициализации некоторой статики. Не конструктор по умолчанию или предоставленный компилятором, но пустой определяемый пользователем. Я попытался сократить код до 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 - поведение одинаковое. Я очень ценю ссылки на стандарт / документацию.

Ответы на вопрос(2)

Ваш ответ на вопрос