在 C++ 中使用 unordered_set 作为 unordered_map 的键时出现的问题
Problems when using unordered_set as the key of unordered_map, in C++
原题有点长,这里简化一下
我需要创建一组带有相关整数的字符串,假设是一个训练组。然后我需要创建许多培训组。我想在一个容器中管理所有培训组。所以我决定使用 boost::unordered_map<> 键为 std::unordered_set。因为,BOOST 具有标准 C++ 容器的哈希值。
简化代码如下:
#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;
}
但是,代码没有成功编译。有许多神秘的警告和错误。错误如下:
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> ]
我不知道这个错误的根源在哪里以及如何解决它。如果编译器无法归档unordered_set的散列函数,错误信息将包含"Hash"或"Key"等字样。然而,它只是说了一些关于类型转换的东西,看起来类似于散列函数。所以,我感到很困惑。
谁能给点建议。我在 Windows 8.
上使用 Visual Studio 2013
PS:当我将Keyunordered_set<string>
改为set<string>
或vector<string>
时,程序编译成功。但是还是不知道是什么原因,也不知道如果确定要用unordered_set<string>
作为key怎么解决。
Boost 不 为std::unordered_set
提供散列函数,散列函数列表包含例如一个 std::set
:
http://www.boost.org/doc/libs/1_61_0/doc/html/hash/reference.html#idp6283424-bb
所以必须自己提供hash函数,使用时比较容易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;
}
原题有点长,这里简化一下
我需要创建一组带有相关整数的字符串,假设是一个训练组。然后我需要创建许多培训组。我想在一个容器中管理所有培训组。所以我决定使用 boost::unordered_map<> 键为 std::unordered_set。因为,BOOST 具有标准 C++ 容器的哈希值。
简化代码如下:
#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;
}
但是,代码没有成功编译。有许多神秘的警告和错误。错误如下:
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> ]
我不知道这个错误的根源在哪里以及如何解决它。如果编译器无法归档unordered_set的散列函数,错误信息将包含"Hash"或"Key"等字样。然而,它只是说了一些关于类型转换的东西,看起来类似于散列函数。所以,我感到很困惑。
谁能给点建议。我在 Windows 8.
上使用 Visual Studio 2013PS:当我将Keyunordered_set<string>
改为set<string>
或vector<string>
时,程序编译成功。但是还是不知道是什么原因,也不知道如果确定要用unordered_set<string>
作为key怎么解决。
Boost 不 为std::unordered_set
提供散列函数,散列函数列表包含例如一个 std::set
:
http://www.boost.org/doc/libs/1_61_0/doc/html/hash/reference.html#idp6283424-bb
所以必须自己提供hash函数,使用时比较容易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;
}