I've been looking at the constructors of unordered_set. Is it not possible to construct an unordered_set with a custom allocator instance WITHOUT setting the number of hash buckets? I'd really rather not mess with implementation details because I want a custom allocator, and the type provides no definitions for the default value. MSDN only gives like three overloads for the constructor, none of which are terribly useful.
Edit: Holy crap. My STL implementation of std::hash won't specialize for strings with a custom allocator type- it can only do the explicit typedefs std::string and std::wstring. I mean, I can understand not wanting to try to hash random character strings, but just because it's got a custom allocator? This disgusts me.
tokens(std::unordered_set<string>().bucket_count(), std::hash<string>(), std::equal_to<string>(), stl_wrapper::hash_set<string>::allocator_type(this))
template<typename Char, typename CharTraits, typename Allocator> class std::hash<std::basic_string<Char, CharTraits, Allocator>>
: public std::unary_function<std::basic_string<Char, CharTraits, Allocator>, std::size_t> {
public:
size_t operator()(const std::basic_string<Char, CharTraits, Allocator>& ref) const {
return std::hash<std::basic_string<Char, CharTraits>>()(std::basic_string<Char, CharTraits>(ref.begin(), ref.end()));
}
};
Solves the problems, but redundant constructions and copying? Ewwwww.
That's strange, but you are right. I suppose the thought was that it's overkill to support all possible parameter combinations, with defaults.
The best way I can think to handle this is to construct an empty unordered_set
with all default settings, get the default bucket count from it using unordered_set::bucket_count
, and then use that as input when you instantiate the container you actually want.
unordered_set<int> temp;
size_t buckets = temp.bucket_count;
unordered_set<string> actual(buckets, Hash(), Pred(),
YourAllocator(param1 /*, etc */));