23

I have the following code:

//MyClass.h
class MyClass {
public:
    typedef std::map<std::string, int> OpMap;
    static OpMap opMap_;     
    // (more methods)
};

//MyClass.cpp
//Init opMap_
MyClass::opMap_["x"] = 1; //compilation error

How can I (statically) initialize opMap_?

Yun
  • 3,056
  • 6
  • 9
  • 28
YAKOVM
  • 9,805
  • 31
  • 116
  • 217
  • 1
    whats the compilation error you get? – Syntactic Fructose Nov 19 '12 at 23:35
  • see that [SO question](http://stackoverflow.com/questions/138600/initializing-a-static-stdmapint-int-in-c) – didierc Nov 19 '12 at 23:35
  • @Need4Sleep : on VS10 ,I get "error C2057: expected constant expression","error C2466: cannot allocate an array of constant size 0" – YAKOVM Nov 19 '12 at 23:39
  • @didierc - I saw that.It didn`t help – YAKOVM Nov 19 '12 at 23:41
  • @Yakov: is this a new version of [this question](http://stackoverflow.com/questions/13463825/using-array-of-value-type-for-the-stlmap)? – Mr.C64 Nov 19 '12 at 23:58
  • @Mr.C64 : IT is different question ,since the way of initialization cahnged – YAKOVM Nov 20 '12 at 00:01
  • possible duplicate of [C++, can I statically initialize a std::map at compile time](http://stackoverflow.com/questions/2172053/c-can-i-statically-initialize-a-stdmap-at-compile-time) – Peter O. Nov 20 '12 at 00:57

3 Answers3

46

If you're using C++11, you could use initializer lists:

//MyClass.h
class MyClass {
public:
      typedef std::map<std::string, int> OpMap;
      static OpMap opMap_;
};

//MyClass.cpp
MyClass::OpMap MyClass::opMap_ = { 
    { "x", 1 }
}; 

If you don't have access to a compiler that supports the C++11 standard, you could do the following:

//MyClass.h
class MyClass {
public:
      typedef std::map<std::string, int> OpMap;
      static OpMap opMap_;
private:
      static OpMap init_map() {
          OpMap some_map;
          some_map["x"] = 1;
          return some_map;
      }
};

//MyClass.cpp
MyClass::OpMap MyClass::opMap_ = init_map();
mfontanini
  • 21,410
  • 4
  • 65
  • 73
  • @mfontanini : I know that,but I use VS10 – YAKOVM Nov 19 '12 at 23:41
  • @mfontanini : Ok.Thanks - I understand I need a kind of init map.Can you guide me about the function content? – YAKOVM Nov 19 '12 at 23:57
  • 1
    @Yakov it basically creates a local map, initializes it with what you want and returns it by value. You then initialize your static member `opMap_` using the result of calling that function. – mfontanini Nov 19 '12 at 23:59
  • Just in case, somebody is looking to initialize an empty map -> http://stackoverflow.com/questions/11247407/initialize-a-static-private-map-as-empty – Behroz Sikander Jan 22 '16 at 13:31
  • thanks ... _still_ must use c++98 on some projects, smh – yano Jun 06 '19 at 19:34
5

As you are using VS2010, you need to initialize your static member in MyClass.cpp, in front of any other member function definitions. call MyClass::InitMap() if you want to initialize opMap_.

MyClass.h

class MyClass
{
public:
  MyClass(void);
  ~MyClass(void);
public:
   typedef std::map<std::string, int> OpMap;
   static OpMap opMap_;    
   static void InitMap();
};

MyClass.cpp

std::map<std::string, int> MyClass::opMap_;
MyClass::MyClass(void)
{
   InitMap(); // just sample if you want to initialize opMap_ inside MyClass constructor
}

void InitMap()
{
  MyClass::opMap_["x"] = 1;
}
billz
  • 44,644
  • 9
  • 83
  • 100
  • it is not clear.Please give more details.What you wrote looks like declaration I already have in MyClass.h – YAKOVM Nov 19 '12 at 23:46
  • 1
    it's very clear. It's a definition of static member and it calls default std::map constructor. In your MyClass.h, it's static member declaration not definition. – billz Nov 19 '12 at 23:48
  • @bills - OK ,I got about defintion .But even if I do std::map MyClass::opMap_; and immidiatly want to init omMap_ : MyClass::opMap_["x"] = 1; I get the same compilation error – YAKOVM Nov 19 '12 at 23:55
  • You need to do operations inside functions. see my updated answer – billz Nov 20 '12 at 00:00
  • 4
    This is a bad solution. You'll be initializing the map each time a `MyClass` object is constructed. – mfontanini Nov 20 '12 at 00:01
  • @billz I did as you said but it still gives compilation error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const std::string' – YAKOVM Nov 20 '12 at 00:09
  • Don't tell me you didn't `#include ` in MyClass.h? – billz Nov 20 '12 at 00:10
  • It's not a bad solution if you add a static bool to see if the map is already initialized... – Papsicle Jun 11 '14 at 13:41
3

In C++ 17 you can add inline

//MyClass.h
class MyClass {
public:
    typedef std::map<std::string, int> OpMap;
    inline static OpMap opMap_;     
    // (more methods)
};
docp
  • 307
  • 1
  • 9