The original problem is kind of long, so I simplify it here.
I need to create a group of strings, with a relevent integer, let's say a training group. Then I need to create many training groups. I want to manage all the training groups in a single container. So I decided to use boost::unordered_map<> with the key being std::unordered_set. Because, the BOOST has hash value for the standard C++ container.
The simplified code are as follows:
#include <string>
#include <unordered_set>
#include <utility>
#include<boost/unordered_map.hpp>
using namespace std;
int main()
{
boost::unordered_map< unordered_set<string>, int> training_groups;
pair<unordered_set<string>, int> a_training_group;
training_groups.insert(a_training_group);
return 0;
}
However, the code doesn't compile successfully. There are many cryptic warnings and an error. The error is as follows:
1>C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xhash(30): error C2440: 'type cast' : cannot convert from 'const std::unordered_set<std::string,std::hash<_Kty>,std::equal_to<_Kty>,std::allocator<_Kty>>' to 'size_t'
1> with
1> [
1> _Kty=std::string
1> ]
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1> C:\Program Files\boost\boost_1_59_0\boost/functional/hash/extensions.hpp(262) : see reference to function template instantiation 'size_t stdext::hash_value<T>(const _Kty &)' being compiled
1> with
1> [
1> T=std::unordered_set<std::string,std::hash<std::string>,std::equal_to<std::string>,std::allocator<std::string>>
1> , _Kty=std::unordered_set<std::string,std::hash<std::string>,std::equal_to<std::string>,std::allocator<std::string>>
1> ]
I don't know where is the origin of this error and how to solve it. If the compiler cannot file the hash function of unordered_set, the error information will contains words like "Hash" or "Key". However, it just says something about type conversion, which looks similar to hash function. So, I feel confused.
Can anyone provide some advice. I am using Visual Studio 2013 on Windows 8.
PS: when I changed the Key unordered_set<string>
to set<string>
or vector<string>
, the program compiles successfully. But I still don't know the reason, and don't know how to solve the problem if I am determined to use unordered_set<string>
as the key.
Boost does not provide a hash function for std::unordered_set
, the list of hash functions contains e.g. one for std::set
:
http://www.boost.org/doc/libs/1_61_0/doc/html/hash/reference.html#idp6283424-bb
So you must provide your own hash function, which is relatively easy when using boost::hash_range
:
#include <string>
#include <unordered_set>
#include <utility>
#include <boost/functional/hash/hash_fwd.hpp>
namespace boost
{
template <class K, class C, class A>
std::size_t hash_value(const std::unordered_set<K, C, A>& v)
{
return boost::hash_range(v.begin(), v.end());
}
} // namespace boost
#include <boost/functional/hash.hpp>
#include <boost/unordered_map.hpp>
int main()
{
boost::unordered_map<std::unordered_set<std::string>, int> training_groups;
std::pair<std::unordered_set<std::string>, int> a_training_group;
training_groups.insert(a_training_group);
return 0;
}