Этот вопрос трудно сформулировать, в первую очередь из-за терминов «создание экземпляров класса» и «создание экземпляров шаблона». У меня есть шаблонный класс, полный статических функций и членов. Перед первым использованием каждой специализации этого шаблона необходимо выполнить некоторую инициализацию.
Мой первоначальный план состоял в том, чтобы просто дать классу шаблона статический член initializer
, который будет инициализировать статические члены класса шаблона во время его создания при динамической инициализации.
Однако это не работает. Если я явно не вызову код в классе initializer
, компилятор не будет генерировать для него код или хранилище.
Например:
template<typename Tag>
class WorkerPool
{
struct WorkerInitializer
{
void foo() { }
WorkerInitializer() { WorkerPool<Tag>::start(); }
};
friend struct WorkerInitializer;
static WorkerInitializer _initializer;
static void start() { std::cout << "Started" << std::endl; }
public:
static void async() { std::cout << "Async" << std::endl; }
};
template<typename T> typename WorkerPool<T>::WorkerInitializer
WorkerPool<T>::_initializer;
struct GenericWorker { };
int main()
{
WorkerPool<GenericWorker>::async();
}
На выходе получается просто «Асинхронный».
Однако, если я изменю его так, что вызов WorkerPool<T>::async()
вызовет _initializer.foo()
, то инициализатор будет скомпилирован и правильно сконструирован, как я и ожидал.
Почему компилятор отказывается генерировать код для моего статического члена?
Я тестировал Visual Studio 2010/2012, gcc и clang, и все они дали одинаковый результат; мой статический член не построен. Это заставляет меня думать, что стандарт требует такого поведения, но мне трудно понять, почему это может быть.