We are designing some "functional-like" data-structures, where every object is immutable. To represent the empty element of each container, we decided to have a static instance.
What we were doing is defining all those static objects in a single file StaticInit.h, so we had control over the order of definition. That header file was included by the main implementation file.
// StaticInit.h
FunctionalMap FunctionalMap::gEmpty = FunctionalMap();
The templated class and static object
Complication arises when we implemented some templated structures :
// FunctionalArray.h
template <class T_contained>
class FunctionalArray
{
static FunctionalArray gEmpty;
private:
FunctionalArray();
}
template <class T_contained>
FunctionalArray<T_contained> FunctionalArray<T_contained>::gEmpty = FunctionalArray();
The standard
From the standard (and this answer)
A [...] static data member of a class template shall be defined in every translation unit in which it is implicitly instantiated [...], unless the corresponding specialization is explicitly instantiated [...] .
Since we want to avoid explicit instanciation of each static object, it seems we are forced to keep the (templated) definition of the static FunctionalArray::gEmpty
in the header file (the only way we can guarantee that the definition will be present in all the translation unit instantiating a FunctionalArray
).
The problem
Now, we have a (non templated) static object which initialization uses an instance of a templated static object.
// StaticInit.h
#include "FunctionalArray.h"
DependantClass DependantClass::gEmpty = methodReferingToTheEmptyArray();
By including FunctionalArray.h (where the definition of the empty array is done), we would have expected not to get bitten by the static initialization order problem... we could not have been more wrong !
Questions
- Why is the order not specified in our case ? (I would guess that could be because the compiler is still producing only one actual definition of the empty array, and this definition could be in any other compilation unit using it. But guesses are not very satisfying...)
- Is there a way to specify the order of initialization in our case, still using the "consolidated definition file" approach ?