我正静态初始化一个大的(~20kb)std :: unordered_map
const std::unordered_map<std::string, std::string> mapStringToString{
{"AAF", "ELN"}, {"ACT", "POC"}, {"AEK", "THJ"}, {"AFO", "EUP"},
{"AHB", "HYW"}, {"AIB", "GFW"}, {"AJX", "BUX"}, {"ALD", "FKP"},
{"ALX", "LWB"}, {"AMY", "NQB"}, {"AOI", "GUC"}, {"ASW", "VMH"},
{"ATQ", "SXK"}, {"AVL", "ENB"}, {"BCJ", "NSX"}, {"BEM", "QVR"},
{"BGU", "WPU"}, {"BJR", "ZCS"}, {"BJT", "ZTK"}, {"BOY", "FYU"},
...
{"XSJ", "FRR"}, {"XUD", "NUI"}, {"XVH", "QTI"}, {"XVJ", "TGG"},
{"XWK", "AZB"}, {"XYQ", "YTO"}, {"YAG", "ZQR"}, {"YAY", "UJY"},
{"YBN", "FEB"}, {"YCR", "EPQ"}, {"YHU", "UUD"}, {"YIG", "YMJ"},
{"YME", "EEZ"}, {"YNE", "EIU"}, {"YTC", "IOC"}, {"YTS", "JQM"},
{"YUH", "JPF"}, {"ZDY", "LFQ"}, {"ZFY", "YIH"}, {"ZMF", "BPK"},
{"ZPR", "TNG"}, {"ZTM", "DFJ"}, {"ZVB", "ZSV"}, {"ZXH", "IOA"},
{"ZZR", "RQG"}};
并且代码分析抱怨堆栈使用:
C6262 Excessive stack usage Function uses '19920' bytes of stack: exceeds /analyze:stacksize '16384'.. This allocation was for a compiler-generated temporary for 'struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > [249]' at line 0. Consider moving some data to heap. <no file>
如果表中的所有数据都作为unordered_map
构造函数的一部分放在堆栈中,则此警告是合理的。
有更好的方法进行初始化吗?
答案 0 :(得分:2)
任何合理大小的地图最好从文件初始化:除了避免堆栈大小的问题,它也往往更容易维护。另一方面,有可能由于某种原因无法访问该文件,并且将数据嵌入到程序中可能是有利的,特别是当它基本上不可变时。注意,生成的映射的const
没有问题:映射可以由迭代器序列构造,该迭代器可以从文件中读取。以下是此方法的示例:
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
#include <unordered_map>
struct mystring
: std::string {
};
std::istream&
operator>> (std::istream& in, std::pair<mystring, std::string>& p) {
in >> p.first >> p.second;
return in;
}
using pair = std::pair<mystring, std::string>;
using iterator = std::istream_iterator<pair>;
using map_type = std::unordered_map<std::string, std::string>;
map_type const map(iterator(std::ifstream("map.txt") >> std::skipws), iterator());
int main()
{
for (auto const& p: map) {
std::cout << "'" << p.first << "'->'" << p.second << "'\n";
}
}
类型mystring
需要具有输入操作符可以重载的类型:仅使用标准库类型,标准库定义输入操作符是必要的但它不会如此。
由于我们显然可以使用迭代器指定的序列而不是std::initializer_list<...>
,因此在程序中存储数据的替代方法是使用相应元素的静态数组,然后将其用作初始化映射的基础序列。例如:
#include <algorithm>
#include <iostream>
#include <string>
#include <unordered_map>
std::pair<std::string const, std::string> values[] = {
{ "foo1", "bar1" },
{ "foo2", "bar2" },
{ "foo3", "bar3" },
{ "foo4", "bar4" }
};
using map_type = std::unordered_map<std::string, std::string>;
map_type const map(std::begin(values), std::end(values));
int main()
{
for (auto const& p: map) {
std::cout << "'" << p.first << "'->'" << p.second << "'\n";
}
}