c++ - Initializer for static member on template not always called in statically linked library -


i have template class intended enum string conversion. it's based on this solution automatically initializing static variables. full class 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[])     {         (int = 0; < 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 initializing specializes init method particular enum, , instantiates template 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 in 2 cases in library statically linked application, in case init never gets called. initialization same (calling macro in .cpp in library) i've run through couple of possibilities not working, including doesn't referenced in library itself, , enum internal class (grasping @ straws) @ bit of loss now.

under conditions static initalizer object not constructed, hence not calling init?

not answer getting data initialize automatically across libraries, alternative implementation doesn't rely on automatic static initialization , lazy initialized needed:

    // helper obtaining string representations of enum values , vice versa     template <typename labeltype>     class enumhelper     {     public:         typedef boost::bimap<labeltype, std::string > enumbimap;          static const char* tostring(labeltype label)         {             auto const& left = instance().enumbimap_.left;             auto iter = left.find(label);             if (iter != left.end())             {                 return iter->second.c_str();             }             else             {                 return "undefined_enum_value";             }         }          static labeltype toenum(const char* name)         {             auto const& right = instance().enumbimap_.right;             std::string str(name);             auto iter = right.find(str);             check_throw(iter != right.end(), error_missing_value, "enum");              return iter->second;         }          static bool isinitialized() { return true;  }      private:         enumhelper() = delete;         enumhelper(const enumhelper&) = delete;         enumhelper(int numlabels, const char* names[])         {             (int = 0; < numlabels; i++)             {                 std::string str(names[i]);                 enumbimap_.insert(enumbimap::value_type((labeltype)i, str));             }         }         static const enumhelper& instance();          enumbimap enumbimap_;     };      // sets specific enum helper having instance accessor init appropriate label names     #define init_enum_helper(labeltype, labelnames, count) \         template <> \         const enumhelper<labeltype>& enumhelper<labeltype>::instance() \         { \             static enumhelper<labeltype> enumhelper(count, labelnames); \             return enumhelper; \         } 

this set particular enum:

// in .h enum class gamestatelabels {     loading,     intro,     play,     results,     count }; const char* game_state_label_names[];  // in .cpp const char* vse::game_state_label_names[] = {     "loading",     "intro",     "play",     "results" };  init_enum_helper(gamestatelabels, game_state_label_names, (int)gamestatelabels::count) 

if has actual solution original issue, i'm happy try , accept if works :)


Comments

Popular posts from this blog

sublimetext3 - what keyboard shortcut is to comment/uncomment for this script tag in sublime -

java - No use of nillable="0" in SOAP Webservice -

ubuntu - Laravel 5.2 quickstart guide gives Not Found Error -