关于std::Map容器的一点总结

 

 

Map 容器的键值如果是 C++ 内置数据类型, Map 在构造底层的红黑树时会用到这些内置类型的 < 操作来进行元素间的比较操作。

但是当 Map 容器的键值不是内置类型而是自己定义的类型时,比如一个类、一个结构体。此时就要对 Map 的比较函数做一点处理,这种情况还会有两种情况出现:

第一种即为如果 Map 的键值是类的对象是,由于类模板是静态编译的,如果自己定义的 Map 键值没有实现 < 操作符,编译会出错。此时可以定义类的成员函数 bool operator < ( const NodeInfo& rValue ) const(注意了这个const不能少)。这样在构造 Map 的红黑树及针对 Map 进行 find 操作时会自动调用到这个自己重载的“ < ”操作。

第二种情况即为如果 Map 的键值是类对象的指针时,由于编译器把指针当作 32 位的整数来处理,此时会存在潜在的错误:不管你自己定义的类中重载了“ < ”操作符与否,编译都会通过,因为它把指针当作 32 位整数来看待。但是在针对 map 进行 find 操作时不会找到自己想要的结果。此时必须实现自己的比较函数对象,不能再用 Map 默认的比较函数对象了,比如下面的比较函数对象:

class Compare : public std ::binary_function <NodeInfo *,NodeInfo *,bool >

{

public :

bool operator ()( const NodeInfo * plValue , const NodeInfo * rValue )

{

return plValue ->addr .union_addr_mem .dwAddr < rValue ->addr .union_addr_mem .dwAddr ;

}

};

 

std ::map <NodeInfo *,int ,Compare > m_mapList ;

这个 map 类的键值为 NodeInfo * ,值域为 int ,比较函数为 Compare

 

 

针对 std::find() std::find_if() 的区别,它们的源码如下所示:

_InIt _Find(_InIt _First, _InIt _Last, const _Ty& _Val)

{    // find first matching _Val

_DEBUG_RANGE(_First, _Last);

for (; _First != _Last; ++_First)

if (*_First == _Val)

break;

return (_First);

}

_InIt _Find_if(_InIt _First, _InIt _Last, _Pr _Pred)

{    // find first satisfying _Pred

_DEBUG_RANGE(_First, _Last);

_DEBUG_POINTER(_Pred);

for (; _First != _Last; ++_First)

if (_Pred(*_First))

break;

return (_First);

}

Find() find_if() 都是到指定的容器中查找指定的元素。它们在比较元素相同时有不同之处, find() 通过“ == ”操作符进行比较, find_if() 则通过模板参数给定的比较函数对象进行比较。这就说明在你自己的类中要重载 == 操作符,如果你用 find() 的话,重载 operator() 操作符,如果你用 find_if() 的话。

如果容器中存的是对象的指针,想用 find() 函数来搜索容器中的元素,由于 == 号的左操作数不是这个类的对象,必须声明友元函数来比较它们(下面说明重载操作符在什么情况下使用友元,什么情况下使用类成员函数)。如下所示:

friend bool operator == ( const NodeInfo * plValue , const NodeInfo & rValue )

{

return plValue ->addr .union_addr_mem .dwAddr == rValue .addr .union_addr_mem .dwAddr ;

}

当使用 find_if() 进行操作时,则要根据容器中所存放的内容来定义 operator() 操作符。例如:

bool operator () (const NodeInfo rValue )

{

return addr .union_addr_mem .dwAddr == rValue .addr .union_addr_mem .dwAddr ;

}

 

bool operator () (const NodeInfo * rValue )

{

return addr .union_addr_mem .dwAddr == rValue ->addr .union_addr_mem .dwAddr ;

}

 

什么时候定义类成员操作符重载,什么时候定义非类成员操作符重载?

  答:( 1 )如果一个重载操作符是类成员,那么只有当跟它一起使用的左操作数是该类对象时,   它才会被调用,如果该操作符的左操作数必须是其他类型,那么重载操作符必须是非类成员操 作符重载。

  (2 C++ 要求,赋值( = ),下标 [ ] ),调用( () )和成员访问箭头( -> )操作符必须被指定为类成员操作符,否则错误。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值