tags:

views:

9049

answers:

6

What is the right way of initializing a static map? Do we need a static function that will initialize it?

+27  A: 

Using Boost.Assign:

#include <map>
#include "boost/assign.hpp"
using namespace std;
using namespace boost::assign;


map<int, int> m = map_list_of (1,2) (3,4) (5,6) (7,8);
Ferruccio
Every time I see something like that done with C++, I think of all the horrendous template code that must be behind it. Good example!
Greg Hewgill
I know what you mean, but in this case I don't think it would be that bad. I think it just overrides operator() to insert a pair into the map and returns a reference to the object so that you can chain calls.
Ferruccio
It is implemented "basically" as an overloaded operator, but if you ever have a syntax error, enjoy that line of code. It pulls in 15 different .hpp's for something that would take you a minute or two. Code for fun? Use it; otherwise, consider the cost to time/size.
hazzen
Boost is great. Wonderful stuff in there. Problem in my case : we can't use it as a company guideline. Not standard enough, not easy enough for the average developer ( not my phrasing ).
QBziZ
The beauty of all the horrendous template code that implements these utilities is that it is neatly encapsulated in a library and the end user rarely needs to deal with the complexity.
Steve Guidi
+9  A: 

I would wrap the map inside a static object, and put the map initialisation code in the constructor of this object, this way you are sure the map is created before the initialisation code is executed.

Drealmer
I'm with you on this one. It's also a tad faster :)
QBziZ
Tad faster than what? A global static with an initializer? No, it's not (remember about RVO).
Pavel Minaev
+23  A: 

Best way is to use a function:

#include <map>

using namespace std;

map<int,int> create_map()
{
  map<int,int> m;
  m[1] = 2;
  m[3] = 4;
  m[5] = 6;
  return m;
}

map<int,int> m = create_map();
PierreBdR
+17  A: 
Vite Falcon
I'm using your first sample as <int,string> to bind error-numbers (from an enum) with messages - it is working like a charm - thank you.
slashmais
@slashmais: Glad it came useful to you :)
Vite Falcon
+2  A: 

This is similar to PierreBdR, without copying the map.

#include <map>

using namespace std;

bool create_map(map<int,int> &m)
{
  m[1] = 2;
  m[3] = 4;
  m[5] = 6;
  return true;
}

static map<int,int> m;
static bool _dummy = create_map (m);
eduffy
It probably wouldn't have been copied anyway.
GMan
... because of (N)RVO: http://en.wikipedia.org/wiki/Return_value_optimization
Georg Fritzsche
+3  A: 

Here is another way that uses the 2-element data constructor. No functions are needed to initialize it.

#include <map>
#include <string>

typedef std::map<std::string, int> MyMap;

const MyMap::value_type rawData[] = {
   MyMap::value_type("hello", 42),
   MyMap::value_type("world", 88),
};
const int numElems = sizeof rawData / sizeof rawData[0];
MyMap myMap(rawData, rawData + numElems);
Brian Neal