std::map 如何使用结构体作为自定义键值
2017-07-26 10:35
429 查看
转自:http://blog.csdn.net/u011417605/article/details/50895097
在使用map时,有时候我们需要自定义键值,才能符合程序的需要。
比如我们需要使用自定义的结构体来作为map的键值:
[cpp]
view plain
copy
struct Test
{
int x;
int y;
};
这样直接使用的话,在编译时会出问题:
[cpp]
view plain
copy
1>------ Build started: Project: MapRemove, Configuration: Debug Win32 ------
1> Source.cpp
1>d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(193): error C2784: 'bool std::operator <(const std::tuple<_Types...> &,const std::tuple<_Types1...> &)' : could not deduce template argument for 'const std::tuple<_Types...> &' from 'const Test'
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\tuple(480) : see declaration of 'std::operator <'
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(192) : while compiling class template member function 'bool std::less<_Kty>::operator ()(const _Ty &,const _Ty &) const'
1> with
1> [
1> _Kty=Test
1> , _Ty=Test
1> ]
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\map(228) : see reference to function template instantiation 'bool std::less<_Kty>::operator ()(const _Ty &,const _Ty &) const' being compiled
1> with
1> [
1> _Kty=Test
1> , _Ty=Test
1> ]
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\type_traits(572) : see reference to class template instantiation 'std::less<_Kty>' being compiled
1> with
1> [
1> _Kty=Test
1> ]
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\xtree(1023) : see reference to class template instantiation 'std::is_empty<std::less<_Kty>>' being compiled
1> with
1> [
1> _Kty=Test
1> ]
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\map(70) : see reference to class template instantiation 'std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>' being compiled
1> with
1> [
1> _Kty=Test
1> , _Ty=std::string
1> , _Pr=std::less<Test>
1> , _Alloc=std::allocator<std::pair<const Test,std::string>>
1> ]
1> f:\xdd\xaudio2\mapremove\source.cpp(12) : see reference to class template instantiation 'std::map<Test,std::string,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' being compiled
1> with
1> [
1> _Kty=Test
1> , _Ty=std::string
1> ]
1>d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(193): error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const Test'
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\xtree(2259) : see declaration of 'std::operator <'
1>d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(193): error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const Test'
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstring(2545) : see declaration of 'std::operator <'
1>d:\program files (x86)\microsoft
4000
visual studio 12.0\vc\include\xstddef(193): error C2784: 'bool std::operator <(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const _Elem *' from 'const Test'
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstring(2535) : see declaration of 'std::operator <'
1>d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(193): error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const Test'
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstring(2525) : see declaration of 'std::operator <'
1>d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(193): error C2784: 'bool std::operator <(const std::move_iterator<_RanIt> &,const std::move_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::move_iterator<_RanIt> &' from 'const Test'
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(1997) : see declaration of 'std::operator <'
1>d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(193): error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const Test'
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(1155) : see declaration of 'std::operator <'
1>d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(193): error C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'const Test'
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(971) : see declaration of 'std::operator <'
1>d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(193): error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const Test'
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\utility(230) : see declaration of 'std::operator <'
1>d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(193): error C2676: binary '<' : 'const Test' does not define this operator or a conversion to a type acceptable to the predefined operator
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
看错误是说,键值无法比较。因为map的键值是自动比较后进插入的,键值是递增的。
现在我们自定义的键值,编译器无法进行比较,找不到类似的模板,所以报错。
既然是没有‘<’,那我们自己重载小于操作符应该就可以了:
[cpp]
view plain
copy
struct Test
{
int x;
int y;
bool operator < (const Test &o) const
{
return x < o.x || y < o.y;
}
};
重载后,重新编译,顺利通过。测试代码如下:
[cpp]
view plain
copy
#include <map>
#include <iostream>
struct Test
{
int x;
int y;
bool operator < (const Test &o) const
{
return x < o.x || y < o.y;
}
};
int main()
{
std::map<Test, std::string> mapTest;
Test test = { 1, 2 };
mapTest[test] = "Test1";
for (auto it = mapTest.begin(); it != mapTest.end();it++)
{
std::cout << it->first.x << " " << it->first.y << " " << it->second.c_str() << std::endl;
}
return 0;
}
在使用map时,有时候我们需要自定义键值,才能符合程序的需要。
比如我们需要使用自定义的结构体来作为map的键值:
[cpp]
view plain
copy
struct Test
{
int x;
int y;
};
这样直接使用的话,在编译时会出问题:
[cpp]
view plain
copy
1>------ Build started: Project: MapRemove, Configuration: Debug Win32 ------
1> Source.cpp
1>d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(193): error C2784: 'bool std::operator <(const std::tuple<_Types...> &,const std::tuple<_Types1...> &)' : could not deduce template argument for 'const std::tuple<_Types...> &' from 'const Test'
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\tuple(480) : see declaration of 'std::operator <'
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(192) : while compiling class template member function 'bool std::less<_Kty>::operator ()(const _Ty &,const _Ty &) const'
1> with
1> [
1> _Kty=Test
1> , _Ty=Test
1> ]
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\map(228) : see reference to function template instantiation 'bool std::less<_Kty>::operator ()(const _Ty &,const _Ty &) const' being compiled
1> with
1> [
1> _Kty=Test
1> , _Ty=Test
1> ]
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\type_traits(572) : see reference to class template instantiation 'std::less<_Kty>' being compiled
1> with
1> [
1> _Kty=Test
1> ]
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\xtree(1023) : see reference to class template instantiation 'std::is_empty<std::less<_Kty>>' being compiled
1> with
1> [
1> _Kty=Test
1> ]
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\map(70) : see reference to class template instantiation 'std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>' being compiled
1> with
1> [
1> _Kty=Test
1> , _Ty=std::string
1> , _Pr=std::less<Test>
1> , _Alloc=std::allocator<std::pair<const Test,std::string>>
1> ]
1> f:\xdd\xaudio2\mapremove\source.cpp(12) : see reference to class template instantiation 'std::map<Test,std::string,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' being compiled
1> with
1> [
1> _Kty=Test
1> , _Ty=std::string
1> ]
1>d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(193): error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const Test'
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\xtree(2259) : see declaration of 'std::operator <'
1>d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(193): error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const Test'
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstring(2545) : see declaration of 'std::operator <'
1>d:\program files (x86)\microsoft
4000
visual studio 12.0\vc\include\xstddef(193): error C2784: 'bool std::operator <(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const _Elem *' from 'const Test'
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstring(2535) : see declaration of 'std::operator <'
1>d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(193): error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const Test'
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstring(2525) : see declaration of 'std::operator <'
1>d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(193): error C2784: 'bool std::operator <(const std::move_iterator<_RanIt> &,const std::move_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::move_iterator<_RanIt> &' from 'const Test'
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(1997) : see declaration of 'std::operator <'
1>d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(193): error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const Test'
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(1155) : see declaration of 'std::operator <'
1>d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(193): error C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'const Test'
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(971) : see declaration of 'std::operator <'
1>d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(193): error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const Test'
1> d:\program files (x86)\microsoft visual studio 12.0\vc\include\utility(230) : see declaration of 'std::operator <'
1>d:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(193): error C2676: binary '<' : 'const Test' does not define this operator or a conversion to a type acceptable to the predefined operator
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
看错误是说,键值无法比较。因为map的键值是自动比较后进插入的,键值是递增的。
现在我们自定义的键值,编译器无法进行比较,找不到类似的模板,所以报错。
既然是没有‘<’,那我们自己重载小于操作符应该就可以了:
[cpp]
view plain
copy
struct Test
{
int x;
int y;
bool operator < (const Test &o) const
{
return x < o.x || y < o.y;
}
};
重载后,重新编译,顺利通过。测试代码如下:
[cpp]
view plain
copy
#include <map>
#include <iostream>
struct Test
{
int x;
int y;
bool operator < (const Test &o) const
{
return x < o.x || y < o.y;
}
};
int main()
{
std::map<Test, std::string> mapTest;
Test test = { 1, 2 };
mapTest[test] = "Test1";
for (auto it = mapTest.begin(); it != mapTest.end();it++)
{
std::cout << it->first.x << " " << it->first.y << " " << it->second.c_str() << std::endl;
}
return 0;
}
相关文章推荐
- std::map 如何使用结构体作为自定义键值
- 使用用户自定义类型作为std::map的…
- 【C++】自定义结构体作为map的key
- std::map 如何插入键值对
- Hadoop中 使用自定义的Writable,作为value在map和reduce传递参数。
- 如何正确使用指针(指针作为输出型参数)与结构体指针作为函数参数
- map 自定义结构体当键值
- 如何在MAP中使用结构体
- 使用kafka作为springcloud bus的消息总线,以及如何自定义总线事件
- (原創) 如何使用subscripting的方式新增std::map? (C/C++) (STL)
- c++中如何关联两个变量的值-键值对,c++map的使用
- Database-UVa1592(如何构建一个二元组作为map的键值)
- map结构体作为key值的使用
- 用仿函数实现以std::string作为key的map自定义排序
- 使用STL去除std::vector自定义结构体重复项
- STL: unordered_map 自定义键值类型的使用(C++)
- map 自定义类型作为键值
- 如何统计出一篇文章出现的文字个数? (高级) (使用std::map)
- 使用std::set作为用户自定义类型的…
- stl容器之--自定义结构体作为stl容器元素成员的使用