I have a template class intended to help with enum string conversion. It's based on this solution to automatically initializing static variables. The full class is as follows:
template <typename LabelType>
class EnumHelper
{
public:
static const char* ToString(LabelType label)
{
return enumBimap_.left.at(label);
}
static LabelType ToEnum(const char* name)
{
return enumBimap_.right.at(name);
}
static bool IsInitialized() { return initialized_; }
private:
typedef boost::bimap<LabelType, const char*> EnumBimap;
EnumHelper() = delete;
EnumHelper(const EnumHelper&) = delete;
static void Init(int numLabels, const char* names[])
{
for (int i = 0; i < numLabels; i++)
{
enumBimap_.insert(EnumBimap::value_type((LabelType)i, names[i]));
}
initialized_ = true;
}
class Initializer
{
public:
Initializer();
};
static EnumBimap enumBimap_;
static bool initialized_;
static Initializer initializer_;
friend class Initializer;
};
template <typename LabelType>
typename EnumHelper<LabelType>::EnumBimap EnumHelper<LabelType>::enumBimap_;
template <typename LabelType>
bool EnumHelper<LabelType>::initialized_ = false;
template <typename LabelType>
typename EnumHelper<LabelType>::Initializer EnumHelper<LabelType>::initializer_;
The macro for initializing it specializes the Init method for the particular enum, and instantiates the template for that enum:
#define INIT_ENUM_HELPER(labelType, labelNames, count) \
template <> \
EnumHelper<labelType>::Initializer::Initializer() \
{ \
EnumHelper<labelType>::Init(count, labelNames); \
} \
template class EnumHelper<labelType>;
Now I'm using this successfully in two cases in a library statically linked to my application, but in another case the Init never gets called. The initialization is exactly the same (calling the macro in a .cpp in the library) I've run through a couple of possibilities for it not working, including that it doesn't get referenced in the library itself, and that the enum was initially internal to a class (grasping at straws) but I really am at a bit of a loss now.
Under what conditions would that static Initalizer object not be constructed, hence not calling the Init?