Initializing a static std::map in C++

2019-01-01 06:08发布

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

标签: c++ stdmap
11条回答
永恒的永恒
2楼-- · 2019-01-01 06:39

Here is another way that uses the 2-element data constructor. No functions are needed to initialize it. There is no 3rd party code (Boost), no static functions or objects, no tricks, just simple C++:

#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);

Since I wrote this answer C++11 is out. You can now directly initialize STL containers using the new initializer list feature:

const MyMap myMap = { {"hello", 42}, {"world", 88} };
查看更多
与风俱净
3楼-- · 2019-01-01 06:41

You have some very good answers here, but I'm to me, it looks like a case of "when all you know is a hammer"...

The simplest answer of to why there is no standard way to initialise a static map, is there is no good reason to ever use a static map...

A map is a structure designed for fast lookup, of an unknown set of elements. If you know the elements before hand, simply use a C-array. Enter the values in a sorted manner, or run sort on them, if you can't do this. You can then get log(n) performance by using the stl::functions to loop-up entries, lower_bound/upper_bound. When I have tested this previously they normally perform at least 4 times faster than a map.

The advantages are many fold... - faster performance (*4, I've measured on many CPU's types, it's always around 4) - simpler debugging. It's just easier to see what's going on with a linear layout. - Trivial implementations of copy operations, should that become necessary. - It allocates no memory at run time, so will never throw an exception. - It's a standard interface, and so is very easy to share across, DLL's, or languages, etc.

I could go on, but if you want more, why not look at Stroustrup's many blogs on the subject.

查看更多
余生无你
4楼-- · 2019-01-01 06:42

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();
查看更多
与君花间醉酒
5楼-- · 2019-01-01 06:43

You can try:

std::map <int, int> mymap = 
{
        std::pair <int, int> (1, 1),
        std::pair <int, int> (2, 2),
        std::pair <int, int> (2, 2)
};
查看更多
闭嘴吧你
6楼-- · 2019-01-01 06:46

For example:

const std::map<LoggerLevel, const char*> g_logLevelsDescriptions =
{
    { LoggerLevel::llNothing, "Logging disabled"            },
    { LoggerLevel::llInfo,    "Base information"            },
    { LoggerLevel::llWarn,    "Warnings"                    },
    { LoggerLevel::llError,   "Errors"                      },
    { LoggerLevel::llDebug,   "All information: debug-mode" }
};
查看更多
怪性笑人.
7楼-- · 2019-01-01 06:47

Using C++11:

#include <map>
using namespace std;

map<int, char> m = {{1, 'a'}, {3, 'b'}, {5, 'c'}, {7, 'd'}};

Using Boost.Assign:

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

map<int, char> m = map_list_of (1, 'a') (3, 'b') (5, 'c') (7, 'd');
查看更多
登录 后发表回答