在 C++ 中初始化静态 std::map<int, int>

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/138600/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:09:10  来源:igfitidea点击:

Initializing a static std::map<int, int> in C++

c++stlstdmap

提问by Nithin

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

初始化静态地图的正确方法是什么?我们是否需要一个静态函数来初始化它?

回答by Ferruccio

Using C++11:

使用 C++11:

#include <map>
using namespace std;

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

Using Boost.Assign:

使用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');

回答by PierreBdR

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

回答by Vite Falcon

It's not a complicated issue to make something similar to boost. Here's a class with just three functions, including the constructor, to replicate what boost did (almost).

制作类似于 boost 的东西并不是一个复杂的问题。这是一个只有三个函数的类,包括构造函数,来复制 boost 所做的(几乎)。

template <typename T, typename U>
class create_map
{
private:
    std::map<T, U> m_map;
public:
    create_map(const T& key, const U& val)
    {
        m_map[key] = val;
    }

    create_map<T, U>& operator()(const T& key, const U& val)
    {
        m_map[key] = val;
        return *this;
    }

    operator std::map<T, U>()
    {
        return m_map;
    }
};

Usage:

用法:

std::map mymap = create_map<int, int >(1,2)(3,4)(5,6);

The above code works best for initialization of global variables or static members of a class which needs to be initialized and you have no idea when it gets used first but you want to assure that the values are available in it.

上面的代码最适用于需要初始化的类的全局变量或静态成员的初始化,您不知道它何时首先被使用,但您想确保其中的值可用。

If say, you've got to insert elements into an existing std::map... here's another class for you.

如果说,您必须将元素插入到现有的 std::map 中……这是另一个适合您的类。

template <typename MapType>
class map_add_values {
private:
    MapType mMap;
public:
    typedef typename MapType::key_type KeyType;
    typedef typename MapType::mapped_type MappedType;

    map_add_values(const KeyType& key, const MappedType& val)
    {
        mMap[key] = val;
    }

    map_add_values& operator()(const KeyType& key, const MappedType& val) {
        mMap[key] = val;
        return *this;
    }

    void to (MapType& map) {
        map.insert(mMap.begin(), mMap.end());
    }
};

Usage:

用法:

typedef std::map<int, int> Int2IntMap;
Int2IntMap testMap;
map_add_values<Int2IntMap>(1,2)(3,4)(5,6).to(testMap);

See it in action with GCC 4.7.2 here: http://ideone.com/3uYJiH

在此处查看 GCC 4.7.2 的实际效果:http: //ideone.com/3uYJiH

############### EVERYTHING BELOW THIS IS OBSOLETE #################

############### 下面的一切都是过时的#################

EDIT: The map_add_valuesclass below, which was the original solution I had suggested, would fail when it comes to GCC 4.5+. Please look at the code above for how to addvalues to existing map.

编辑map_add_values下面的课程是我建议的原始解决方案,当涉及到 GCC 4.5+ 时会失败。请查看上面的代码以了解如何向现有地图添加值。


template<typename T, typename U>
class map_add_values
{
private:
    std::map<T,U>& m_map;
public:
    map_add_values(std::map<T, U>& _map):m_map(_map){}
    map_add_values& operator()(const T& _key, const U& _val)
    {
        m_map[key] = val;
        return *this;
    }
};

Usage:

用法:

std::map<int, int> my_map;
// Later somewhere along the code
map_add_values<int,int>(my_map)(1,2)(3,4)(5,6);

NOTE: Previously I used a operator []for adding the actual values. This is not possible as commented by dalle.

注意:以前我使用 aoperator []来添加实际值。正如 dalle 所评论的,这是不可能的。

##################### END OF OBSOLETE SECTION #####################

##################### 过时部分结束####################

回答by Brian Neal

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++:

这是使用 2 元素数据构造函数的另一种方法。不需要任何函数来初始化它。没有第 3 方代码 (Boost),没有静态函数或对象,没有技巧,只有简单的 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:

自从我写了这个答案 C++11 就出来了。您现在可以使用新的初始化列表功能直接初始化 STL 容器:

const MyMap myMap = { {"hello", 42}, {"world", 88} };

回答by isnullxbh

For example:

例如:

const std::map<LogLevel, const char*> g_log_levels_dsc =
{
    { LogLevel::Disabled, "[---]" },
    { LogLevel::Info,     "[inf]" },
    { LogLevel::Warning,  "[wrn]" },
    { LogLevel::Error,    "[err]" },
    { LogLevel::Debug,    "[dbg]" }
};

If map is a data member of a class, you can initialize it directly in header by the following way (since C++17):

如果 map 是类的数据成员,则可以通过以下方式直接在 header 中对其进行初始化 (C++17 起):

// Example

template<>
class StringConverter<CacheMode> final
{
public:
    static auto convert(CacheMode mode) -> const std::string&
    {
        // validate...
        return s_modes.at(mode);
    }

private:
    static inline const std::map<CacheMode, std::string> s_modes =
        {
            { CacheMode::All, "All" },
            { CacheMode::Selective, "Selective" },
            { CacheMode::None, "None" }
            // etc
        };
}; 

回答by Drealmer

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.

我会将地图包装在一个静态对象中,并将地图初始化代码放入该对象的构造函数中,这样您就可以确保在执行初始化代码之前创建了地图。

回答by user3826594

Just wanted to share a pure C++ 98 work around:

只是想分享一个纯 C++ 98 解决方法:

#include <map>

std::map<std::string, std::string> aka;

struct akaInit
{
    akaInit()
    {
        aka[ "George" ] = "John";
        aka[ "Joe" ] = "Al";
        aka[ "Phil" ] = "Sue";
        aka[ "Smitty" ] = "Yando";
    }
} AkaInit;

回答by Dmitry Oberemchenko

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

回答by eduffy

This is similar to PierreBdR, without copying the map.

这类似于PierreBdR,无需复制地图。

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

回答by Emanuele Benedetti

If you are stuck with C++98 and don't want to use boost, here there is the solution I use when I need to initialize a static map:

如果您坚持使用 C++98 并且不想使用 boost,这里有我在需要初始化静态地图时使用的解决方案:

typedef std::pair< int, char > elemPair_t;
elemPair_t elemPairs[] = 
{
    elemPair_t( 1, 'a'), 
    elemPair_t( 3, 'b' ), 
    elemPair_t( 5, 'c' ), 
    elemPair_t( 7, 'd' )
};

const std::map< int, char > myMap( &elemPairs[ 0 ], &elemPairs[ sizeof( elemPairs ) / sizeof( elemPairs[ 0 ] ) ] );