Reputation: 37
std::unordered_map<std::string, std::string> mimeMap = {
#define STR_PAIR(K,V) std::pair<std::string, std::string>(K,V)
#include "MimeTypes.inc"
};
File MimeTypes.inc is like:
STR_PAIR("3dm", "x-world/x-3dmf"),
STR_PAIR("3dmf", "x-world/x-3dmf"),
STR_PAIR("a", "application/octet-stream"),
STR_PAIR("aab", "application/x-authorware-bin"),
STR_PAIR("aam", "application/x-authorware-map"),
STR_PAIR("aas", "application/x-authorware-seg"),
STR_PAIR("abc", "text/vnd.abc"),
STR_PAIR("acgi", "text/html"),
STR_PAIR("afl", "video/animaflex"),
STR_PAIR("ai", "application/postscript"),
STR_PAIR("aif", "audio/aiff"),
I am very confused. How does this code initialise an unordered_map
?
Upvotes: 2
Views: 233
Reputation: 1
From the reference documentation you have the option to use a std::initializer_list
constructor (5):
map( std::initializer_list<value_type> init, const Compare& comp = Compare(), const Allocator& alloc = Allocator() );
the macro builds one from the std::pair
s and the #include
directive replaces the text within the {}
braces. Finally this evaluates to:
std::unordered_map<std::string, std::string> mimeMap = {
#define STR_PAIR(K,V) std::pair<std::string, std::string>(K,V)
std::pair<std::string, std::string>("3dm", "x-world/x-3dmf"),
std::pair<std::string, std::string>("3dmf", "x-world/x-3dmf"),
std::pair<std::string, std::string>("a", "application/octet-stream"),
std::pair<std::string, std::string>("aab", "application/x-authorware-bin"),
std::pair<std::string, std::string>("aam", "application/x-authorware-map"),
std::pair<std::string, std::string>("aas", "a");
std::pair<std::string, std::string>(pplication/x-authorware-seg"),
std::pair<std::string, std::string>("abc", "text/vnd.abc"),
std::pair<std::string, std::string>("acgi", "text/html"),
std::pair<std::string, std::string>("afl", "video/animaflex"),
std::pair<std::string, std::string>("ai", "application/postscript"),
std::pair<std::string, std::string>("aif", "audio/aiff"),
};
Upvotes: 1
Reputation: 16431
#include
does textual copy-paste. It's almost as if you had written the following directly:
std::unordered_map<std::string, std::string> mimeMap = {
#define STR_PAIR(K,V) std::pair<std::string, std::string>(K,V)
STR_PAIR("3dm", "x-world/x-3dmf"),
// ...
STR_PAIR("aif", "audio/aiff"),
};
Now, STR_PAIR
is a preprocessor macro that replaces its arguments with std::pair<std::string, std::string>(K,V)
, K
and V
being the parameters of the macro. For example, the above snippet is no different than:
std::unordered_map<std::string, std::string> mimeMap = {
std::pair<std::string, std::string>("3dm", "x-world/x-3dmf"),
// ...
std::pair<std::string, std::string>("aif", "audio/aiff"),
};
If you're using gcc or clang, you can use -E
command line option to get preprocessed output and see for yourself. Be aware that it'll be quite big, though.
Finally, such pair
is used to copy-initialize elements of mimeMap
.
This code is also buggy, because map
's value_type
is pair<const Key, Value>
, so STR_PAIR
should actually create std::pair<std::string const, std::string>
Upvotes: 10