I am statically initializing a large (~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"}};
and code analysis is complaining about stack usage:
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>
This warning is reasonable if all the data in the table is put on the stack as part of the unordered_map
constructor.
Is there a better way to do this initialization?
A map of any reasonable size is probably best initialised from a file: aside from avoiding the problem with the stack size, it also tends to be easier to maintain. On the other hand, there is a chance that the file is not accessible for whatever reason and embedding the data, especially when it is essentially immutable, into the program may be favourable. Note, that there is no problem with
const
ness of the resulting map: the map can be constructed by a sequence of iterator which could read from a file. Here is an example of this approach:The type
mystring
is needed to have a type for which the input operator can be overloaded: using only standard library types it would be necessary that the standard library defines an input operator but it doesn't do so.Since we can, obviously, use a sequence specified by iterator rather than an
std::initializer_list<...>
an alternative storing the data inside the program is a static array with the corresponding elements which is then used as the underlying sequence to initialise map. For example: