C++ C+中使用无序#u集作为无序#u映射键时的问题+;

C++ C+中使用无序#u集作为无序#u映射键时的问题+;,c++,boost,hash,containers,unordered,C++,Boost,Hash,Containers,Unordered,最初的问题有点长,所以我在这里简化它 我需要创建一组字符串,带有一个相关的整数,比如说一个训练组。然后我需要创建许多培训小组。我想在一个容器中管理所有培训组。所以我决定使用boost::unordered_映射,键为std::unordered_set。因为,升压对标准C++容器有哈希值。 简化代码如下: #include <string> #include <unordered_set> #include <utility> #include<boos

最初的问题有点长,所以我在这里简化它

我需要创建一组字符串,带有一个相关的整数,比如说一个训练组。然后我需要创建许多培训小组。我想在一个容器中管理所有培训组。所以我决定使用boost::unordered_映射,键为std::unordered_set。因为,升压对标准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>          ]
#包括
#包括
#包括
#包括
使用名称空间std;
int main()
{
boost::无序映射<无序集,int>训练组;
配对a_培训组;
培训组。插入(培训组);
返回0;
}
但是,代码没有成功编译。有许多神秘的警告和错误。错误如下:

#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>          ]
1>C:\Program Files(x86)\Microsoft Visual Studio 12.0\VC\include\xhash(30):错误C2440:“类型转换”:无法从“常量std::无序集”转换为“大小”
1> 与
1>          [
1> _Kty=std::string
1>          ]
1> 没有可执行此转换的用户定义的转换运算符,或者无法调用该运算符
1> C:\ProgramFiles\boost\boost\u 1\u 59\u 0\boost/functional/hash/extensions.hpp(262):请参阅正在编译的函数模板实例化“size\t stdext::hash\u value(const\u Kty&)”的参考
1> 与
1>          [
1> T=std::无序的_集
1> ,_Kty=std::无序集
1>          ]
我不知道这个错误的根源在哪里,以及如何解决它。如果编译器无法对无序_集的哈希函数进行归档,则错误信息将包含“哈希”或“键”等字。然而,它只是说了一些关于类型转换的事情,它看起来类似于散列函数。所以,我感到困惑

谁能提供一些建议。我正在Windows 8上使用Visual Studio 2013


PS:当我将键
无序集
更改为
向量
时,程序编译成功。但是我仍然不知道原因,也不知道如果我决定使用
unordered\u set
作为键,如何解决这个问题。

Boost没有
std::unordered\u set
提供哈希函数,哈希函数列表包含一个,例如
std::set

因此,您必须提供自己的哈希函数,这在使用
boost::hash\u 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;
}
#包括
#包括
#包括
#包括
名称空间提升
{
模板
标准::大小\u t哈希值(常量标准::无序集&v)
{
返回boost::hash_范围(v.begin(),v.end());
}
}//名称空间提升
#包括
#包括
int main()
{
boost::无序地图培训组;
标准:配对a_培训组;
培训组。插入(培训组);
返回0;
}

为什么你认为集合必须是地图的关键?对于我真正的问题,培训组的第二部分实际上是另一个自定义类型的无序集合。在这篇文章中,我用一个整数来简化这个问题。因此,与自定义类型的无序_集相比,字符串的无序_集更适合用作键。此外,我可以将键无序_集更改为刚集或向量。但是,无序_集对于将来的操作来说更方便、更快。@JohnSmith:使用
无序_集
作为键并不是很快,因为比较谓词非常慢。它可以是设置大小的二次型(正是因为集合无序)。非常感谢。我错过了BOOST没有为std::unordered_集提供散列函数。顺便问一下,STD::unOrdEdStEt被认为是标准的C++容器吗?是的,很容易为STD::unOrdEdStEt集提供散列函数。一个有效的散列函数有点棘手。为什么你认为boost不能提供一个?提示:你链接的页面说为什么。@ JohnSmith:C++的标准库的一部分,因为C++ +1个挑战可能会碰到,而且我不知道Boosi::hhash范围的细节,但是如果迭代顺序对于哈希函数来说是重要的,那么两个等价的集合可能最终以不同的哈希值结束。通过对文档的快速检查,它看起来并不与订单无关。