//定义在STL实现代码stl_algo.h中
template <class InputIterator, class Predicate>
InputIterator find_if(InputIterator first, InputIterator last,Predicate pred) 

......{
while (first != last && !pred(*first)) ++first;
return first;
}
可见STL是把find_if定义为一个函数模板,该函数模板接收两个数据类型,InputItearator是输入的迭代器,Predicate是用于比较的函数或者函数对象(仿函数)。这里有个问题需要注意,那就是为什么这里要将比较函数定义为函数对象呢?这个问题在下面进行分析下。
1.map的查找方法
如果给定map的一个second值,要求在该map中找出与之相符的map索引,则需要使用STL的算法find_if来查找,而find_if的比较函数需写为函数对象。下面是一个示例:
//用于map比较的函数对象
class CMapFindIf

...{
public:

CMapFindIf(string szFindString):_szFindString(szFindString)...{};

~CMapFindIf()...{};
public:
bool operator()(map<string,string>::value_type &it)

...{
//TODO:这里写比较函数的算法,如果认为和给定值相符,则返回true,否则返//回false
if ( _szFindString.find(it.second) != string::npos )
return true;
else
return false;
} 
private:
string _szFindString; 
};
这个用于比较的函数对象实际上重载了()运算符,因为在find_if函数中是这样调用该函数对象的pred(*first)),实际上是将它作为一个bool key_comp() 函数使用的,在函数对象中的()运算符的形参类型是比较对象的value_type,是因为find_if中传入*first的缘故。而value_type到底是什么类型,下面有相信定义。
上面给出了仿函数的写法,下面是针对map的find_if使用方法。
上面的vector查找方式是调用函数的查找,仅能查找符合某一条件的数据,而在实际情况中可能需要查找不同条件的数据,所以此处我们也使用函数对象(仿函数)方法实现一个。
class CVecFindFun

...{
public:
CVecFindFun(string szFindString):m_szFindString(szFindString)

...{}

~CVecFindFun()...{}
private:
string m_szFindString;
public:
//bool operator() (string &vecValue)
bool operator() (vector<string>::value_type &vecValue)

...{
if ( vecValue == m_szFindString )
return true;
else
return false;
} 
};
template <class T, class Alloc = alloc>
class vector 

...{
public:
typedef T value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type* iterator;
typedef const value_type* const_iterator;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
.......
};
2.map插入时的排序
把比较函数写成函数对象才可以的,比如:
class CompEr

...{
public:
bool operator()(const string& ls, const string& rs) const

...{
return ls < rs; 
}
};
typedef std::map<string, int, CompEr> mymap;
int main(int argc, char* argv[])

...{
//TODO:
return 0;
}
map<string, string> _m_FileAcceptExeName;
char szBuf[100];//查找值
if( find_if(_m_FileAcceptExtName.begin(),_m_FileAcceptExtName.end(),
CMapFindIf(string(szBuf))) != _m_FileAcceptExtName.end() )
return true;
else
return false;
在stl_map.h头文件中定义有以下的map::value_type 。可见map的value_type是pair类型的数据类型。
template <class Key, class T, class Compare, class Alloc = alloc>
class map 

...{
public:
// typedefs:
typedef Key key_type;
typedef T data_type;
typedef T mapped_type;
typedef pair<const Key, T> value_type;
typedef Compare key_compare;
private:
typedef rb_tree<key_type, value_type, 
select1st<value_type>, key_compare, Alloc> rep_type;
rep_type t; // red-black tree representing map
public:
typedef typename rep_type::pointer pointer;
typedef typename rep_type::const_pointer const_pointer;
typedef typename rep_type::reference reference;
typedef typename rep_type::const_reference const_reference;
typedef typename rep_type::iterator iterator;
typedef typename rep_type::const_iterator const_iterator;
typedef typename rep_type::reverse_iterator reverse_iterator;
typedef typename rep_type::const_reverse_iterator
const_reverse_iterator;
typedef typename rep_type::size_type size_type;
typedef typename rep_type::difference_type difference_type;
........
}; 
template <class Key, class Value, class KeyOfValue, class Compare,
class Alloc = alloc>
class rb_tree 

...{
protected:
typedef void* void_pointer;
typedef __rb_tree_node_base* base_ptr;
typedef __rb_tree_node<Value> rb_tree_node;
typedef simple_alloc<rb_tree_node, Alloc> rb_tree_node_allocator;
typedef __rb_tree_color_type color_type;
public:
typedef Key key_type;
typedef Value value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef rb_tree_node* link_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
......
}; 
2.vector的查找方法
vector的查找这里有两种方法,一个是定义查找函数,另一个是定义仿函数。
if ( vto.size() == 1 && 
find_if(vto.begin(), vto.end(),find_qq) != vto.end() )

...{
//TODO: 
}
bool find_qq(string &szMail)//find_qq(vector<string>::value_type )

...{
if ( szMail.find("@qq.com") != string::npos )
return true;
return false;
}
本文详细介绍如何在C++ STL的map和vector中使用find_if进行高效查找,并展示了如何通过函数对象实现灵活的比较逻辑。此外,还介绍了map插入排序的方法。

3249

被折叠的 条评论
为什么被折叠?



