stl::map 重载 operator“<”注意事项

本文介绍了STL中的map容器,它使用一对一的哈希存储数据,并通过红黑树保持数据有序。当map的关键字为自定义类型时,必须重载<运算符以支持排序。文中给出了一个struct indices的示例,展示了如何正确重载<,确保在比较时逻辑严密,避免排序错误。理解并正确实现这个运算符对于使用map存储自定义类型至关重要。

一、首先明确map定义

map是STL的一个关联容器,它提供一对一的hash。

  • 第一个可以称为关键字(key),每个关键字只能在map中出现一次;
  • 第二个可能称为该关键字的值(value);

二、注意事项

如果定义的map的关键字(key)是标准库中的类型如(int)(double)(string)等等,则无需重载“<”;

如果定义的map的关键字(key)是自己定义的 结构/类 对象,则注意要重载“<”。

struct indices{ unsigned int v, vt; }
map<indices,int> indicesMap;

如下图:


struct indices
{
	unsigned int v, vt;
	bool operator<(const struct indices & right)const   //重载<运算符
	{
			if (this->vt < right.vt)
				return true;
			else if (this->vt == right.vt)
			{
				if (this->v < right.v)
					return true;	
			}
			return false;
	}
};

1.为什么?

因为map內部的实现自建一颗红黑树,这颗树具有对数据自动排序的功能。在map内部所有的数据都是有序的。比如一个班级中,每个学生的学号跟他的姓名就存在著一对一映射的关系。所以如果不对自定义对象重载“<”函数,会导致map无法完成自动排序,程序会报错:

2.怎么办?

逻辑很简单,只需要定义一个逻辑严密的" operator<"函数即可。

逻辑严密是指在自定义对象的任何情况下,都有唯一的大小比较结果。而且不会出现

a<b,b<c ,而c<a的情况。

代码如下:


struct indices
{
	unsigned int v, vt;
	bool operator<(const struct indices & right)const   //重载<运算符
	{
			if (this->vt < right.vt)
				return true;
			else if (this->vt == right.vt)
			{
				if (this->v < right.v)
					return true;	
			}
			return false;
	}
};

 

 

/home/shz/Project/appHDQt6/udptask.cpp:1353: error: no match for ‘operator<’ (operand types are ‘const QHostAddress’ and ‘const QHostAddress’) In file included from /usr/include/c++/9/utility:70, from ../../Qt6/6.7.3/gcc_64/include/QtCore/qglobal.h:15, from ../../Qt6/6.7.3/gcc_64/include/QtCore/QtCore:4, from ../appHDQt6/paramdef.h:4, from ../appHDQt6/deviceparameterstorage.h:4, from ../appHDQt6/udptask.h:4, from ../appHDQt6/udptask.cpp:15: /usr/include/c++/9/bits/stl_pair.h: In instantiation of ‘constexpr bool std::operator<(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&) [with _T1 = QHostAddress; _T2 = short unsigned int]’: /usr/include/c++/9/bits/stl_function.h:386:20: required from ‘constexpr bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = std::pair<QHostAddress, short unsigned int>]’ /usr/include/c++/9/bits/stl_tree.h:2564:8: required from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::find(const _Key&) [with _Key = std::pair<QHostAddress, short unsigned int>; _Val = std::pair<const std::pair<QHostAddress, short unsigned int>, long long unsigned int>; _KeyOfValue = std::_Select1st<std::pair<const std::pair<QHostAddress, short unsigned int>, long long unsigned int> >; _Compare = std::less<std::pair<QHostAddress, short unsigned int> >; _Alloc = std::allocator<std::pair<const std::pair<QHostAddress, short unsigned int>, long long unsigned int> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::pair<QHostAddress, short unsigned int>, long long unsigned int> >]’ /usr/include/c++/9/bits/stl_map.h:1169:29: required from ‘std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::find(const key_type&) [with _Key = std::pair<QHostAddress, short unsigned int>; _Tp = long long unsigned int; _Compare = std::less<std::pair<QHostAddress, short unsigned int> >; _Alloc = std::allocator<std::pair<const std::pair<QHostAddress, short unsigned int>, long long unsigned int> >; std::map<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::pair<QHostAddress, short unsigned int>, long long unsigned int> >; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::pair<QHostAddress, short unsigned int>]’ ../../Qt6/6.7.3/gcc_64/include/QtCore/qmap.h:370:14: required from ‘T& QMap<Key, T>::operator[](const Key&) [with Key = std::pair<QHostAddress, short unsigned int>; T = long long unsigned int]’ ../appHDQt6/udptask.cpp:1353:32: required from here /usr/include/c++/9/bits/stl_pair.h:455:24: error: no match for ‘operator<’ (operand types are ‘const QHostAddress’ and ‘const QHostAddress’) 455 | { return __x.first < __y.first | ~~~~~~~~~~^~~~~~~~~~~ /usr/include/c++/9/bits/stl_pair.h:454:5: note: candidate: ‘template<class _T1, class _T2> constexpr bool std::operator<(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)’ 454 | operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) | ^~~~~~~~ /usr/include/c++/9/bits/stl_pair.h:454:5: note: template argument deduction/substitution failed: /usr/include/c++/9/bits/stl_pair.h:455:24: note: ‘const QHostAddress’ is not derived from ‘const std::pair<_T1, _T2>’ 455 | { return __x.first < __y.first | ~~~~~~~~~~^~~~~~~~~~~ 是什么问题?
最新发布
07-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值