I've been switching my code over from std::map
to std::unordered_map
where appropriate. With std::map
, I typically write the following just to make sure the key cannot be modified:
std::map<const std::string, int>
Frankly, I never checked if this const
was of any value. This has always compiled and worked with g++.
Now, with std::unordered_map
, the following fails to link with g++ 4.5.1.
std::unordered_map<const std::string, std::string> m;
m["foo"] = "bar";
with this link error:
U开发者_如何学Cndefined symbols:
"std::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const>::operator()(std::basic_string<char, std::char_traits<char>, std::allocator<char> >) const"
, referenced from:
The fix is simple, to remove const
, but besides that, is there even a point in STL with any of the associative container classes to use a const
key type? Are there no methods that let you get a reference to the key for any associative container?
The associative containers only expose the (key,value) pair as std::pair<const key_type, mapped_type>
, so the additional const on the key type is superfluous.
std::unordered_map<std::string const, std::string>
uses std::hash<std::string const>
, but no specialization exists for hash<std::string const>
. However, there is one for std::hash<std::string>
. You can provide one if you wish to use a std::string const
as your key:
struct constant_string_hash {
std::size_t operator () (std::string const &s) const {
return hash<std::string>{}(s);
}
};
You can then declare your std::unordered_map
like this:
std::unordered_map<std::string const, std::string, constant_string_hash> m;
m["test key"] = "test value";
精彩评论