Recently, I’ve been using one of the lesser-used STL features- custom allocators, and I need some serious help in reducing my semantic overhead. Take for example, the definition of an unordered map, which maps filenames to an unordered map of a pair of ints and a shared_ptr to a Token, but using a custom allocator.
typedef std::pair<int, int> token_key_type;
typedef std::unordered_map<
token_key_type,
std::shared_ptr<Token>,
std::hash<token_key_type>,
std::equal_to<token_key_type>,
Allocator<
std::pair<
const token_key_type,
std::shared_ptr<
Token
>
>
>
> filename_map_value_type;
std::unordered_map<
string,
filename_map_value_type,
std::hash<string>,
std::equal_to<string>,
Allocator<
std::pair<
const string,
filename_map_value_type
>
>
> tokens;
That’s 404 characters of definitions. And then to construct it, I have to pass in the default for every template argument, except the Allocator, which can’t be default constructed, AND the bucket count, for which no definition exists, resulting in another 168 characters just to construct the damn thing. Plus, of course, the same again every time I want to insert, because the value type of the first map has to be constructed like that too.
Is there any way that all of this can be avoided without having to write my own unordered_map? It’s seriously starting to slow down my productivity.
Edit: Sorry! I meant, in general, for STL containers, not just unordered_map specifically, it’s just the worst case. I’ve also got this problem with regular map, unordered_set, etc, and can’t go writing a function to do all of this for all of the possible STL containers I might need invidually.
icecrime’s solution can also be done with only slightly more ugliness on older compilers via the code below. You also may be able to add factory functions to simplify construction.