Когда шаблон класса имеет статический член, нам нужно дополнительное (шаблонное) определение этого члена. Теперь это определение на самом деле не создается сразу, скорее, необходимо создать экземпляр окружающего шаблона, а статическое поле нужно использовать «odr-used». Пока все хорошо.
Тем не менее, я получаю удивительное поведение с GCC / Linux. (г ++ 4,7 и 7,2 )
#include <iostream>
using std::cout;
using std::endl;
template<typename T>
class Factory
{
public:
T val;
Factory()
: val{}
{
cout << "Factory-ctor val="<<val<<endl;
}
};
template<typename T>
class Front
{
public:
static Factory<T> fac;
Front()
{
cout << "Front-ctor val="<<fac.val<<endl;
fac.val += 100;
}
T&
operate ()
{
cout << "Front-operate val="<<fac.val<<endl;
++ fac.val;
return fac.val;
}
};
template<typename T>
Factory<T> Front<T>::fac;
namespace {
Front<int> front;
int global_int = front.operate();
}
int
main (int, char**)
{
Front<int> fint;
int& i = fint.operate();
cout << "main: val="<<i<<endl;
cout << "global_int.......="<<global_int<<endl;
return 0;
}
В анонимном пространстве имен мы сначала создаем статический экземпляр Front, а затем вызываем на нем функцию operate()
, которая использует статический элемент фабрики. И выходные данные, и значения ясно указывают на то, что ctor статического элемента вызывается после того, как было использовано. Что может быть причиной такого поведения? Для меня это кажется нелогичным: если фабрика управляет каким-то ресурсом, ресурс будет пропущен.
~$ g++ --version
g++ (Ubuntu 7.2.0-8ubuntu3.2) 7.2.0
~$ g++ --std=gnu++17 demo.cpp -o demo
~$ ./demo
Front-ctor val=0
Front-operate val=100
Factory-ctor val=0
Front-ctor val=0
Front-operate val=100
main: val=101
global_int.......=101
Я пробовал также Clang (3.5), который просто segfaults.
PS : очевидный обходной путь - превратить фабрику в синглтон Meyers. Тем не менее, я ожидаю, что система ctors и dtors будет герметичной в такой базовой ситуации (обратите внимание, что мы не имеем в виду какую-либо статичность из других модулей перевода). Таким образом, я в первую очередь заинтересован в рассуждениях , объясняющих это наблюдение.