C++ 函数对象
2015-07-05 19:08
525 查看
1、考虑下面的需求,从集合中找到一个与当前Student相等的学生,如下:
int main(int argc, char* argv[])
{
Student s1(20,"Andy");
Student s2(23,"Bill");
Student s3(28,"Caroline");
Student s4(27,"David");
Student s5(21,"Eric");
vector<Student> stuVec;
stuVec.push_back(s1);
stuVec.push_back(s2);
stuVec.push_back(s3);
stuVec.push_back(s4);
stuVec.push_back(s5);
Student target(23,"Bill");
vector<Student>::iterator iter = find(stuVec.begin(),stuVec.end(),target);
return 0;
}
注意:调用find方法,Student要重载成员操作符==,或者重载普通操作符==,因为find使用==比较两个对象是否相等。
2、需求变更,找出一个年龄比target大的学生,怎么办?
使用函数对象,函数对象有一个成员_stu,使用target初始化_stu,重载(),比较target与序列中的每个对象
class Finder
{
public:
Finder(const Student& stu):_stu(stu)
{
}
bool operator()(const Student& rhs)
{
if(rhs._Age>_stu._Age)
{
return true;
}
return false;
}
private:
Student _stu;
};
iter = find_if(stuVec.begin(),stuVec.end(),Finder(target));
注:假如对于teacher的集合,也要同样的需求,找出一个年龄比target大的教师,可以将Finder修改成模板类。
3、有没有其他的办法呢?
使用greater<Student>可以比较Student的大小,一个是变量,一个是参照物,而find_if的第三个参数,隐式接口是 Pred(*First),只接受一个参数。
使用bind2nd 对greater<Student>和参照物封装,对外暴露接口接受一个参数,对内调用greater(参数,参照物),greater使用>比较大小,对Student进行>操作符过载。
bool operator>(const Student& lhs,const Student& rhs)
{
return lhs._Age > rhs._Age;
}
iter = find_if(stuVec.begin(),stuVec.end(),bind2nd(greater<Student>(),target));
4、其他办法呢?
不过载操作符,偏特化一个greater,用于比较age大小。如下:
template <>
struct greater<Student>: public binary_function<Student, Student, bool>
{
bool operator()(const Student& _Left, const Student& _Right) const
{
return (_Left._Age > _Right._Age);
}
};
iter = find_if(stuVec.begin(),stuVec.end(),bind2nd(greater<Student>(),target));
5、因为偏特化只有一个,能不能自己写一个类似greater的方法对象呢,并且是可以使用bind2nd适配的。
注意:为了可适配,需要继承 public binary_function<Student, Student, bool>
struct StudentNameCompare: public binary_function<Student, Student, bool>
{
bool operator()(const Student& _Left, const Student& _Right) const
{
return (_Left._Age > _Right._Age);
}
};
iter = find_if(stuVec.begin(),stuVec.end(),bind2nd(StudentNameCompare(),target));
当然也可以使用模板,如下:
template <typename T>
struct StudentNameCompare: public binary_function<T, T, bool>
{
bool operator()(const T& _Left, const T& _Right) const
{
return (_Left._Age > _Right._Age);
}
};
iter = find_if(stuVec.begin(),stuVec.end(),bind2nd(StudentNameCompare<Student>(),target));
6、现在分析2的方法和5的方法,最终的接口都要满足 Pred(*First),只接受一个参数。二者的处理策略不同。 在2中,函数对象,只接受一个参数,但是有一个字段,这个字段用于保存参照物。在5中,函数对象接受两个参数,继承binary_function,使之可适配,然后使用bind2nd 将函数对象和参照物封装起来,对外暴露接口只接受一个参数。
7、考虑下面的需求,找出一个年龄比target小的学生,对于5,只需要使用not1再次适配一下即可,如下:
iter = find_if(stuVec.begin(),stuVec.end(),not1(bind2nd(StudentNameCompare<Student>(),target)));
但是对于2,不行。因为2不是可适配的,要让2是可适配的,需要继承 public unary_function<Student,bool>,如下:
class Finder:public unary_function<Student,bool>
{
public:
Finder(const Student& stu):_stu(stu)
{
}
bool operator()(const Student& rhs) const
{
if(rhs._Age>_stu._Age)
{
return true;
}
return false;
}
private:
Student _stu;
};
当然,也可以使用模板。
int main(int argc, char* argv[])
{
Student s1(20,"Andy");
Student s2(23,"Bill");
Student s3(28,"Caroline");
Student s4(27,"David");
Student s5(21,"Eric");
vector<Student> stuVec;
stuVec.push_back(s1);
stuVec.push_back(s2);
stuVec.push_back(s3);
stuVec.push_back(s4);
stuVec.push_back(s5);
Student target(23,"Bill");
vector<Student>::iterator iter = find(stuVec.begin(),stuVec.end(),target);
return 0;
}
注意:调用find方法,Student要重载成员操作符==,或者重载普通操作符==,因为find使用==比较两个对象是否相等。
2、需求变更,找出一个年龄比target大的学生,怎么办?
使用函数对象,函数对象有一个成员_stu,使用target初始化_stu,重载(),比较target与序列中的每个对象
class Finder
{
public:
Finder(const Student& stu):_stu(stu)
{
}
bool operator()(const Student& rhs)
{
if(rhs._Age>_stu._Age)
{
return true;
}
return false;
}
private:
Student _stu;
};
iter = find_if(stuVec.begin(),stuVec.end(),Finder(target));
注:假如对于teacher的集合,也要同样的需求,找出一个年龄比target大的教师,可以将Finder修改成模板类。
3、有没有其他的办法呢?
使用greater<Student>可以比较Student的大小,一个是变量,一个是参照物,而find_if的第三个参数,隐式接口是 Pred(*First),只接受一个参数。
使用bind2nd 对greater<Student>和参照物封装,对外暴露接口接受一个参数,对内调用greater(参数,参照物),greater使用>比较大小,对Student进行>操作符过载。
bool operator>(const Student& lhs,const Student& rhs)
{
return lhs._Age > rhs._Age;
}
iter = find_if(stuVec.begin(),stuVec.end(),bind2nd(greater<Student>(),target));
4、其他办法呢?
不过载操作符,偏特化一个greater,用于比较age大小。如下:
template <>
struct greater<Student>: public binary_function<Student, Student, bool>
{
bool operator()(const Student& _Left, const Student& _Right) const
{
return (_Left._Age > _Right._Age);
}
};
iter = find_if(stuVec.begin(),stuVec.end(),bind2nd(greater<Student>(),target));
5、因为偏特化只有一个,能不能自己写一个类似greater的方法对象呢,并且是可以使用bind2nd适配的。
注意:为了可适配,需要继承 public binary_function<Student, Student, bool>
struct StudentNameCompare: public binary_function<Student, Student, bool>
{
bool operator()(const Student& _Left, const Student& _Right) const
{
return (_Left._Age > _Right._Age);
}
};
iter = find_if(stuVec.begin(),stuVec.end(),bind2nd(StudentNameCompare(),target));
当然也可以使用模板,如下:
template <typename T>
struct StudentNameCompare: public binary_function<T, T, bool>
{
bool operator()(const T& _Left, const T& _Right) const
{
return (_Left._Age > _Right._Age);
}
};
iter = find_if(stuVec.begin(),stuVec.end(),bind2nd(StudentNameCompare<Student>(),target));
6、现在分析2的方法和5的方法,最终的接口都要满足 Pred(*First),只接受一个参数。二者的处理策略不同。 在2中,函数对象,只接受一个参数,但是有一个字段,这个字段用于保存参照物。在5中,函数对象接受两个参数,继承binary_function,使之可适配,然后使用bind2nd 将函数对象和参照物封装起来,对外暴露接口只接受一个参数。
7、考虑下面的需求,找出一个年龄比target小的学生,对于5,只需要使用not1再次适配一下即可,如下:
iter = find_if(stuVec.begin(),stuVec.end(),not1(bind2nd(StudentNameCompare<Student>(),target)));
但是对于2,不行。因为2不是可适配的,要让2是可适配的,需要继承 public unary_function<Student,bool>,如下:
class Finder:public unary_function<Student,bool>
{
public:
Finder(const Student& stu):_stu(stu)
{
}
bool operator()(const Student& rhs) const
{
if(rhs._Age>_stu._Age)
{
return true;
}
return false;
}
private:
Student _stu;
};
当然,也可以使用模板。
相关文章推荐
- c++ primer读书笔记-第八章 标准IO库
- 【学习笔记】【C语言】static和extern对变量的作用
- 【学习笔记】【C语言】static和extern对函数的作用
- C++基于该模型模板包括节目外实例
- C语言中的位操作
- C语言学习笔记:14_内部函数和外部函数
- C++知识点随笔(一):this指针、拷贝构造函数、初始化列表
- 从C语言角度看OC编程里类、类对象
- C语言学习笔记:13_变量和函数的声明与定义
- C语言学习笔记:12_变量的存储方式和生存期
- 【C语言】printf函数和scanf函数典型例子
- C语言-共用体
- C++11初探
- 【C++】通用单链表
- c++ const 类型转化初始化
- 【C/C++学习笔记】memmove()、memcpy()、memccpy()、strcpy()函数整理
- C++一些注意事项
- C语言程序的gcc翻译步骤
- 让c++ 函数返回一个数组
- LRU Cache的C++实现