C++,我可以在编译时静态初始化std :: map吗?

Maw*_*awg 40 c++ embedded stl

如果我编码这个

std::map<int, char> example = {
                                (1, 'a'),
                                (2, 'b'),
                                (3, 'c') 
                              };
Run Code Online (Sandbox Code Playgroud)

然后g ++对我说

deducing from brace-enclosed initializer list requires #include <initializer_list>
in C++98 ‘example’ must be initialized by constructor, not by ‘{...}’   
Run Code Online (Sandbox Code Playgroud)

这让我很烦,因为构造函数是运行时的,理论上可能会失败.

当然,如果确实如此,它将很快失败并且应该一直这样做,所以我应该快速找到并纠正问题.

但是,我仍然很好奇 - 无论如何在编译时初始化地图,矢量等?


编辑:我应该说我正在为嵌入式系统开发.并非所有处理器都具有C++ 0x编译器.最受欢迎的可能是,但我不想遇到问题并且必须维护2个版本的代码.

至于Boost,我尚未决定.他们在嵌入式系统中使用他们的有限状态机类是多么的愚蠢,所以这就是我在这里编写的事件/事件/状态/ Fsm类.

叹了口气,我想我最好安全地玩,但我希望这个讨论对其他人有帮助.

Dmi*_*try 37

它不是完全静态初始化,但仍然试一试.如果您的编译器不支持C++ 0x,我会选择std :: map的迭代构造函数:

std::pair<int, std::string> map_data[] = {
    std::make_pair(1, "a"),
    std::make_pair(2, "b"),
    std::make_pair(3, "c")
};

std::map<int, std::string> my_map(map_data,
    map_data + sizeof map_data / sizeof map_data[0]);
Run Code Online (Sandbox Code Playgroud)

这非常易读,不需要任何额外的库,应该适用于所有编译器.

  • 请注意,此方法将构造分配内存以保存map_data中的每个临时std :: pair项,将静态声明的字符串复制到pair :: second,然后将文本再次复制到std :: map中,最后销毁临时工.对于大量静态声明的项目,这将是非常浪费的. (7认同)

Art*_*yom 21

不是在C++ 98中.C++ 11支持这一点,所以如果你启用C++ 11标志并包含g ++建议的内容,你可以.

编辑:从gcc 5 C++ 11默认开启

  • 我认为语法应该像{{1,'a'}}; (5认同)

mlo*_*kot 14

您可以使用Boost.Assign库:

#include <boost/assign.hpp>
#include <map>
int main()
{
   std::map<int, char> example = 
      boost::assign::map_list_of(1, 'a') (2, 'b') (3, 'c');
}
Run Code Online (Sandbox Code Playgroud)

但是,正如Neil和其他人在下面的评论中指出的那样,这种初始化发生在运行时,类似于UncleBean的提议.

  • 它不是,"boost :: assign"导致运行时初始化. (2认同)

Unc*_*ens 13

使用C++ 0x,您可能需要一直使用大括号(对每对使用新式语法):

std::map<int, char> example = { {1,'a'}, {2, 'b'}, {3, 'c'} };
Run Code Online (Sandbox Code Playgroud)

构造对的那些括号没有意义.或者,您可以完全命名每对或使用make_pair(就像在C++ 98中一样)

std::map<int, char> example = {
    std::make_pair(1,'a'),
    std::make_pair(2, 'b'),
    std::make_pair(3, 'c')
};
Run Code Online (Sandbox Code Playgroud)

至于在编译时创建这些实例:没有.STL容器全部封装了运行时内存管理.

我想,你真的只有一个编译时的地图,里面有像boost的元编程这样的库(不是100%肯定,如果它是完全正确的,并且没有研究它可能有什么好处):

using namespace boost::mpl;
map<
    pair<integral_c<int, 1>, integral_c<char, 'a'> >,
    pair<integral_c<int, 2>, integral_c<char, 'b'> >,
    pair<integral_c<int, 3>, integral_c<char, 'c'> >
> compile_time_map;
Run Code Online (Sandbox Code Playgroud)