免费注册 查看新帖 |

Chinaunix

广告
  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3701 | 回复: 7
打印 上一主题 下一主题

find_if问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-10-16 13:31 |只看该作者 |倒序浏览
模板:
template <class T>
class ParamCompare
{
public:
    ParamCompare(const std::string& strName) : fname(strName)
    {
    }

    bool operator()(T& ent)
    {
        return (fname.compare(ent.m_strName) == 0);
    }

private:
    std::string fname;
};


调用时:
        std::list<CSessionEnt>::iterator iter;
        iter = std::find_if(m_sessions.begin(), m_sessions.end(), ParamCompare<CSessionEnt>(strName));

其中类CSessionEnt中有m_strName变量,
我不明白的是:
find_if(方法调用时,ParamCompare是怎么调用构造方法和()符号重载的?
是不是这种调用方法是find_if所特有的?

谢谢!!

论坛徽章:
0
2 [报告]
发表于 2006-10-16 14:04 |只看该作者
这是一个仿函数,最主要的地方就是重载了operator(),所以你调用ParamCompare<CSessionEnt>(strName)的时候,可以对()内的string做相关的处理。
不是find_if特有。  大部分STL算法都有仿函数的存在。

论坛徽章:
0
3 [报告]
发表于 2006-10-16 15:56 |只看该作者
原帖由 okmmno1 于 2006-10-16 14:04 发表
这是一个仿函数,最主要的地方就是重载了operator(),所以你调用ParamCompare<CSessionEnt>(strName)的时候,可以对()内的string做相关的处理。
不是find_if特有。  大部分STL算法都有仿函数的存在。



你的意思是不是:
调用ParamCompare<CSessionEnt>(strName)时,仿函数先调用类的构造函数,然后自动调用()重载函数?
仿函数中()的重载参数默认是CSessionEnt吗?
仿函数和一般的模板类在写法上有什么区别呢?只要在模板类中重载了(),就会自动调用吗?
如果从载了类的()操作符,但是不想在构造时调用,又该怎么办呢?

我是第一次接触仿函数,有问的不对的地方请指正.
谢谢!!

论坛徽章:
0
4 [报告]
发表于 2006-10-16 18:59 |只看该作者
传入std::find_if(m_sessions.begin(), m_sessions.end(), ParamCompare<CSessionEnt>(strName));中的参数首先生成一个仿函数对象,在find_if的算法中比较对象的时候再调用仿函数重载的operator()函数,
在find_if的源码中:


  1. template <class InputIterator, class Predicate>
  2. InputIterator find_if(InputIterator first, InputIterator last,
  3.                       Predicate pred) {
  4.   while (first != last && !pred(*first)) ++first;
  5.   return first;
  6. }
复制代码

pred就是你传入find_if生成的仿函数对象,而pred(*first)就是调用的这个仿函数重载的operator()函数.

如果还是不清楚,可以一步一步跟进去调试看看.

论坛徽章:
0
5 [报告]
发表于 2006-10-17 08:44 |只看该作者
非常感谢楼上的解答!
楼上的意思是不是,find_if函数的第三个参数必须重载()操作符?
另外,仿函数的定义是什么?也就是什么样的形式算是仿函数呢?
我在网上找了半天,可是还是不太明白,是不是模板从载了()操作符就是仿函数了?
好像仿函数还和函数指针有什么关系?

谢谢了!

论坛徽章:
0
6 [报告]
发表于 2006-10-17 10:20 |只看该作者
所谓“仿函数”是 functor,泛指可以使用“()”(函数)运算符的对象。比如函数指针都是 functor,因为它们都可以做 fun_ptr(arg_list) 形式的调用。

ReturnType operator() (arg_list) 形式的重载也让一个对象可以以 fun_obj(arg_list) 的形式调用。

而 functor 在使用时是统一的,不论其真实类型是何种,只需要返回值和参数列表一致。

论坛徽章:
0
7 [报告]
发表于 2006-10-17 13:17 |只看该作者
原帖由 cuicp 于 2006-10-17 08:44 发表
非常感谢楼上的解答!
楼上的意思是不是,find_if函数的第三个参数必须重载()操作符?
另外,仿函数的定义是什么?也就是什么样的形式算是仿函数呢?
我在网上找了半天,可是还是不太明白,是不是模板从载了()操作符就 ...


第三个参数不一定非要重载(),比如:
  1. [b]#include <iostream>
  2. #include <boost/tokenizer.hpp>
  3. #include <string>
  4. #include <fstream>
  5. #include <list>

  6. using namespace std;

  7. void print(string str)
  8. {
  9.         cout<<str<<endl;
  10. }
  11. int main()
  12. {
  13.         ifstream in("12345",ios::in);
  14.         string str;
  15.         int i = 0;
  16.         typedef boost::tokenizer<boost::char_separator<char> > Tok;
  17.         boost::char_separator<char>sep("'\t'");
  18.         list<string>mylist;
  19.         while(getline(in,str,'\n'))
  20.                 {
  21.                         mylist.push_back(str);
  22.                         i++;
  23.                 }
  24.         Tok tok(*(++(++mylist.begin())),sep);
  25.         cout<<i<<endl;
  26.         //cout<<*tok.begin()<<endl;
  27.         //for(Tok::iterator iter = tok.begin();iter != tok.end();++iter)
  28.         //{
  29.         //cout<<*iter<<endl;
  30.         //}
  31.         size_t diff = distance(tok.begin(),tok.end());
  32.         cout<<diff<<endl;
  33.         for_each(tok.begin(),tok.end(),print);
  34. }[/b]
复制代码
早上写得一个很烂得测试代码。 你看for_each第三个参数。他是一个函数,没有重载(),
但 “仿函数”必须要重载()了。
找本STL得书看看  上面说得比较详细。

[ 本帖最后由 okmmno1 于 2006-10-17 13:18 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2006-10-17 13:50 |只看该作者
有点明白了,
所谓“仿函数”是 functor,泛指可以使用“()”(函数)运算符的对象?
"functor 在使用时是统一的,不论其真实类型是何种"这句话是不是应该是模板实现仿函数时的特性?

谢谢!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP