map的成员函数没有提供这一功能,对于这个问题,我首先想到的方法是,循环遍历一下,将其中每个元素和比较对象进行比较,就可以了,代码如下(为了方便说明,我将key的类型定义为int,对于其他类型的或是自定义类型的,可能需要自己写比较函数)
1 map<int, int>testMap;
2
3 for (int i = 1; i < 11; ++i)
4 {
5 testMap.insert(make_pair(i, i+100));
6 }
7
8 int nCount = 0;
9 for (itor = testMap.begin(); itor != testMap.end(); ++itor)
10 {
11 if (itor->first < 5)
12 {
13 ++nCount;
14 }
15 }
但是,在网上常看到很多高手都会给我们这样的忠告,在处理STL容器的时候,尽量不要自己去写循环处理。
在STL中,count_if这个算法,正符合我们的要求,而我们只需要提供比较函数就可以了,代码如下:
1 template<class key, class Value>
2 class cmp_less
3 {
4 public:
5 cmp_less(key K)
6 :nKey(K)
7 {
8
9 }
10
11 bool operator()(pair<key, Value> elems)
12 {
13 if (elems.first < nKey)
14 {
15 return true;
16 }
17 else
18 {
19 return false;
20 }
21 }
22 private:
23 key nKey;
24 };
25
26 nCount = count_if(testMap.begin(), testMap.end(), cmp_less<int, int>(5));
文章写到这里也能结束了,但这几天在看bind2nd这个仿函数和别人文章的时候,想改用bind2nd试试,也看看自己掌握的情况,不用不知道,在写代码的时候才发现自己掌握的比较肤浅,尝试了大半天,侯捷老师的STL源码剖析一书也翻了好几次,总算写出来,代码如下:
1 template<class Key, class Value>
2 class myless : public binary_function<pair<Key, Value>, Key, bool>
3 {
4 public:
5 bool operator()(pair<Key, Value> elemnt, Key other) const
6 {
7 if (elemnt.first < other)
8 {
9 return true;
10 }
11 else
12 {
13 return false;
14 }
15 }
16 };
17
18 nCount = count_if(testMap.begin(), testMap.end(), bind2nd(myless<int, int>(), 5));
在这之前我写出了这样的代码,
1 nCount = count_if(testMap.begin(), testMap.end(), bind2nd(less<pair<int, int>>(), make_pair(5, 100)));
这样也可以比较,但有个问题,因为这样写是两个pair比较,而pair比较是这样的,请看源代码:
1 template<class _Ty1, class _Ty2>
2 inline bool operator<(const pair<_Ty1, _Ty2>& _Left, const pair<_Ty1, _Ty2>& _Right)
3 { // test if _Left < _Right for pairs
4 return (_Left.first < _Right.first ||
5 !(_Right.first < _Left.first) && _Left.second < _Right.second);
6 }
不仅比较key,还要比较value,这样必须把右边pair的value的值设的够大才行,这不符合我们要求,我们只要求key做比较。
bind2nd源代码是这样的,请看:
1 template<class _Fn2, class _Ty>
2 inline binder2nd<_Fn2> bind2nd(const _Fn2& _Func, const _Ty& _Right)
3 { // return a binder2nd functor adapter
4 typename _Fn2::second_argument_type _Val(_Right);
5 return (std::binder2nd<_Fn2>(_Func, _Val));
6 }
我们注意到这句代码typename _Fn2::second_argument_type _Val(_Right);
就是右边的值(即做比较的值)要能向_Fn2::second_argument_type转换,而且是由_Fn2提供的,_Fn2::second_argument_type是什么呢,请看
1 template<class _Arg1, class _Arg2, class _Result>
2 struct binary_function
3 { // base class for binary functions
4 typedef _Arg1 first_argument_type;
5 typedef _Arg2 second_argument_type;
6 typedef _Result result_type;
7 };
first_argument_type是左边参数类型,second_argument_type是右边参数类型,由于是map左边是pair,右边我们要求是key的类型,即int,所以我们
的定义这样的
1 template<class Key, class Value>
2 class myless : public binary_function<pair<Key, Value>, Key, bool>
3
就这三个方法,个人感觉还是第二个比较好。