无法使用 user-defined class 作为键创建 two-dimensional unordered_map
Cannot create two-dimensional unordered_map with user-defined class as key
如标题所述,当使用 two-dimensional 映射和 user-defined class 作为钥匙。
这是我要声明的地图:
std::unordered_map<tag, std::map<tag, std::pair<bool, bool>>> transitRights;
下面是 class 标记的声明和 std::hash 函数的特化:
class tag
{
public:
tag();
tag(const char[3]);
tag(const std::string&);
void operator=(const tag&);
const bool operator==(const tag&)const;
operator const std::string()const;
const char& getA()const { return a; }
const char& getB()const { return b; }
const char& getC()const { return c; }
private:
char a, b, c;
};
namespace std
{
template<> class hash<tag>
{
public:
size_t operator()(const tag& _tag) const
{
return hash<char>()(_tag.getA()) ^ hash<char>()(_tag.getB()) ^ hash<char>()(_tag.getC());
}
};
};
尝试编译时,Visual Studio 向我抛出一堆这些神秘的错误消息:
1>C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(600): error C2664: 'std::pair<const _Kty,_Ty>::pair(const std::pair<const _Kty,_Ty> &)' : cannot convert argument 1 from 'const tag' to 'const std::pair<const _Kty,_Ty> &'
1> with
1> [
1> _Kty=int
1> , _Ty=std::pair<bool,bool>
1> ]
1> Reason: cannot convert from 'const tag' to 'const std::pair<const _Kty,_Ty>'
1> with
1> [
1> _Kty=int
1> , _Ty=std::pair<bool,bool>
1> ]
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(723) : see reference to function template instantiation 'void std::allocator<_Other>::construct<_Objty,const tag&>(_Objty *,const tag &)' being compiled
1> with
1> [
1> _Other=std::_Tree_node<std::pair<const int,std::pair<bool,bool>>,void *>
1> , _Objty=std::pair<const int,std::pair<bool,bool>>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(723) : see reference to function template instantiation 'void std::allocator<_Other>::construct<_Objty,const tag&>(_Objty *,const tag &)' being compiled
1> with
1> [
1> _Other=std::_Tree_node<std::pair<const int,std::pair<bool,bool>>,void *>
1> , _Objty=std::pair<const int,std::pair<bool,bool>>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(872) : see reference to function template instantiation 'void std::allocator_traits<_Alloc>::construct<_Ty,const tag&>(std::allocator<_Other> &,_Objty *,const tag &)' being compiled
1> with
1> [
1> _Alloc=std::allocator<std::_Tree_node<std::pair<const int,std::pair<bool,bool>>,void *>>
1> , _Ty=std::pair<const int,std::pair<bool,bool>>
1> , _Other=std::_Tree_node<std::pair<const int,std::pair<bool,bool>>,void *>
1> , _Objty=std::pair<const int,std::pair<bool,bool>>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(872) : see reference to function template instantiation 'void std::allocator_traits<_Alloc>::construct<_Ty,const tag&>(std::allocator<_Other> &,_Objty *,const tag &)' being compiled
1> with
1> [
1> _Alloc=std::allocator<std::_Tree_node<std::pair<const int,std::pair<bool,bool>>,void *>>
1> , _Ty=std::pair<const int,std::pair<bool,bool>>
1> , _Other=std::_Tree_node<std::pair<const int,std::pair<bool,bool>>,void *>
1> , _Objty=std::pair<const int,std::pair<bool,bool>>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xtree(933) : see reference to function template instantiation 'void std::_Wrap_alloc<std::allocator<_Other>>::construct<_Ty,const tag&>(_Ty *,const tag &)' being compiled
1> with
1> [
1> _Other=std::_Tree_node<std::pair<const int,std::pair<bool,bool>>,void *>
1> , _Ty=std::pair<const int,std::pair<bool,bool>>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xtree(933) : see reference to function template instantiation 'void std::_Wrap_alloc<std::allocator<_Other>>::construct<_Ty,const tag&>(_Ty *,const tag &)' being compiled
1> with
1> [
1> _Other=std::_Tree_node<std::pair<const int,std::pair<bool,bool>>,void *>
1> , _Ty=std::pair<const int,std::pair<bool,bool>>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xtree(1176) : see reference to function template instantiation 'std::_Tree_node<std::pair<const _Kty,_Ty>,void *> *std::_Tree_buy<std::pair<const _Kty,_Ty>,std::allocator<std::pair<const _Kty,_Ty>>>::_Buynode<const tag&>(const tag &)' being compiled
1> with
1> [
1> _Kty=int
1> , _Ty=std::pair<bool,bool>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xtree(1176) : see reference to function template instantiation 'std::_Tree_node<std::pair<const _Kty,_Ty>,void *> *std::_Tree_buy<std::pair<const _Kty,_Ty>,std::allocator<std::pair<const _Kty,_Ty>>>::_Buynode<const tag&>(const tag &)' being compiled
1> with
1> [
1> _Kty=int
1> , _Ty=std::pair<bool,bool>
1> ]
1> nation.cpp(600) : see reference to function template instantiation 'std::pair<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,bool> std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::emplace<const tag&>(const tag &)' being compiled
1> with
1> [
1> _Kty=int
1> , _Ty=std::pair<bool,bool>
1> , _Pr=std::less<int>
1> , _Alloc=std::allocator<std::pair<const int,std::pair<bool,bool>>>
1> ]
1> nation.cpp(600) : see reference to function template instantiation 'std::pair<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,bool> std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::emplace<const tag&>(const tag &)' being compiled
1> with
1> [
1> _Kty=int
1> , _Ty=std::pair<bool,bool>
1> , _Pr=std::less<int>
1> , _Alloc=std::allocator<std::pair<const int,std::pair<bool,bool>>>
1> ]
任何对我在这里做错的见解都将不胜感激。
散列必须是 struct
:
namespace std {
template<> struct hash<tag> {
^^^^^^
public:
size_t operator()(const tag& _tag) const {
return hash<char>()(_tag.getA()) ^ hash<char>()(_tag.getB()) ^ hash<char>()(_tag.getC());
}
};
};
编辑:
正如 @6502 正确提到的那样,您还必须定义一个小于 operator<
的值,因为您还使用了带有键 tag
的 std::map
(下面的示例):
bool operator<(tag const &t1, tag const &t2) {
return t1.getA() < t2.getA();
}
问题是嵌套对象是 std::map
(不是 unordered_map
),为此您需要对 tag
.
进行小于比较
但是,您应该能够构建 unordered_map
个 unordered_map
。
如标题所述,当使用 two-dimensional 映射和 user-defined class 作为钥匙。 这是我要声明的地图:
std::unordered_map<tag, std::map<tag, std::pair<bool, bool>>> transitRights;
下面是 class 标记的声明和 std::hash 函数的特化:
class tag
{
public:
tag();
tag(const char[3]);
tag(const std::string&);
void operator=(const tag&);
const bool operator==(const tag&)const;
operator const std::string()const;
const char& getA()const { return a; }
const char& getB()const { return b; }
const char& getC()const { return c; }
private:
char a, b, c;
};
namespace std
{
template<> class hash<tag>
{
public:
size_t operator()(const tag& _tag) const
{
return hash<char>()(_tag.getA()) ^ hash<char>()(_tag.getB()) ^ hash<char>()(_tag.getC());
}
};
};
尝试编译时,Visual Studio 向我抛出一堆这些神秘的错误消息:
1>C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(600): error C2664: 'std::pair<const _Kty,_Ty>::pair(const std::pair<const _Kty,_Ty> &)' : cannot convert argument 1 from 'const tag' to 'const std::pair<const _Kty,_Ty> &'
1> with
1> [
1> _Kty=int
1> , _Ty=std::pair<bool,bool>
1> ]
1> Reason: cannot convert from 'const tag' to 'const std::pair<const _Kty,_Ty>'
1> with
1> [
1> _Kty=int
1> , _Ty=std::pair<bool,bool>
1> ]
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(723) : see reference to function template instantiation 'void std::allocator<_Other>::construct<_Objty,const tag&>(_Objty *,const tag &)' being compiled
1> with
1> [
1> _Other=std::_Tree_node<std::pair<const int,std::pair<bool,bool>>,void *>
1> , _Objty=std::pair<const int,std::pair<bool,bool>>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(723) : see reference to function template instantiation 'void std::allocator<_Other>::construct<_Objty,const tag&>(_Objty *,const tag &)' being compiled
1> with
1> [
1> _Other=std::_Tree_node<std::pair<const int,std::pair<bool,bool>>,void *>
1> , _Objty=std::pair<const int,std::pair<bool,bool>>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(872) : see reference to function template instantiation 'void std::allocator_traits<_Alloc>::construct<_Ty,const tag&>(std::allocator<_Other> &,_Objty *,const tag &)' being compiled
1> with
1> [
1> _Alloc=std::allocator<std::_Tree_node<std::pair<const int,std::pair<bool,bool>>,void *>>
1> , _Ty=std::pair<const int,std::pair<bool,bool>>
1> , _Other=std::_Tree_node<std::pair<const int,std::pair<bool,bool>>,void *>
1> , _Objty=std::pair<const int,std::pair<bool,bool>>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(872) : see reference to function template instantiation 'void std::allocator_traits<_Alloc>::construct<_Ty,const tag&>(std::allocator<_Other> &,_Objty *,const tag &)' being compiled
1> with
1> [
1> _Alloc=std::allocator<std::_Tree_node<std::pair<const int,std::pair<bool,bool>>,void *>>
1> , _Ty=std::pair<const int,std::pair<bool,bool>>
1> , _Other=std::_Tree_node<std::pair<const int,std::pair<bool,bool>>,void *>
1> , _Objty=std::pair<const int,std::pair<bool,bool>>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xtree(933) : see reference to function template instantiation 'void std::_Wrap_alloc<std::allocator<_Other>>::construct<_Ty,const tag&>(_Ty *,const tag &)' being compiled
1> with
1> [
1> _Other=std::_Tree_node<std::pair<const int,std::pair<bool,bool>>,void *>
1> , _Ty=std::pair<const int,std::pair<bool,bool>>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xtree(933) : see reference to function template instantiation 'void std::_Wrap_alloc<std::allocator<_Other>>::construct<_Ty,const tag&>(_Ty *,const tag &)' being compiled
1> with
1> [
1> _Other=std::_Tree_node<std::pair<const int,std::pair<bool,bool>>,void *>
1> , _Ty=std::pair<const int,std::pair<bool,bool>>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xtree(1176) : see reference to function template instantiation 'std::_Tree_node<std::pair<const _Kty,_Ty>,void *> *std::_Tree_buy<std::pair<const _Kty,_Ty>,std::allocator<std::pair<const _Kty,_Ty>>>::_Buynode<const tag&>(const tag &)' being compiled
1> with
1> [
1> _Kty=int
1> , _Ty=std::pair<bool,bool>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xtree(1176) : see reference to function template instantiation 'std::_Tree_node<std::pair<const _Kty,_Ty>,void *> *std::_Tree_buy<std::pair<const _Kty,_Ty>,std::allocator<std::pair<const _Kty,_Ty>>>::_Buynode<const tag&>(const tag &)' being compiled
1> with
1> [
1> _Kty=int
1> , _Ty=std::pair<bool,bool>
1> ]
1> nation.cpp(600) : see reference to function template instantiation 'std::pair<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,bool> std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::emplace<const tag&>(const tag &)' being compiled
1> with
1> [
1> _Kty=int
1> , _Ty=std::pair<bool,bool>
1> , _Pr=std::less<int>
1> , _Alloc=std::allocator<std::pair<const int,std::pair<bool,bool>>>
1> ]
1> nation.cpp(600) : see reference to function template instantiation 'std::pair<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,bool> std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::emplace<const tag&>(const tag &)' being compiled
1> with
1> [
1> _Kty=int
1> , _Ty=std::pair<bool,bool>
1> , _Pr=std::less<int>
1> , _Alloc=std::allocator<std::pair<const int,std::pair<bool,bool>>>
1> ]
任何对我在这里做错的见解都将不胜感激。
散列必须是 struct
:
namespace std {
template<> struct hash<tag> {
^^^^^^
public:
size_t operator()(const tag& _tag) const {
return hash<char>()(_tag.getA()) ^ hash<char>()(_tag.getB()) ^ hash<char>()(_tag.getC());
}
};
};
编辑:
正如 @6502 正确提到的那样,您还必须定义一个小于 operator<
的值,因为您还使用了带有键 tag
的 std::map
(下面的示例):
bool operator<(tag const &t1, tag const &t2) {
return t1.getA() < t2.getA();
}
问题是嵌套对象是 std::map
(不是 unordered_map
),为此您需要对 tag
.
但是,您应该能够构建 unordered_map
个 unordered_map
。