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的比较函数需写为函数对象。下面是一个示例:
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查找方式是调用函数的查找,仅能查找符合某一条件的数据,而在实际情况中可能需要查找不同条件的数据,所以此处我们也使用函数对象(仿函数)方法实现一个。
... {
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;
}
} ;
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插入时的排序
把比较函数写成函数对象才可以的,比如:
... {
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;
}
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类型的数据类型。
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;
........
} ;
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的查找这里有两种方法,一个是定义查找函数,另一个是定义仿函数。
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;
}