考虑以下需求:
统计某个容器中符合规定的元素个数,比如这里规定就是小于某个数(如果有其他需求可以自定义一个仿函数)
来我们来写代码:
#include<iostream>
#include<algorithm>
#include<vector>
#include<iterator>
using namespace std;
template <typename Ty>
bool my_less(Ty i){
return i < 5;
}
int main(int argc,char** argv){
int a[] = {1,2,3,4,5,6,7,8,9,10};
vector<int> vec(a,a+10);
cout<<count_if(vec.begin(),vec.end(),my_less<int>)<<endl;
}
上面的是运用仿函数吗?不是的,并没有重定义()。应该怎么写固定的threshold的仿函数呢?
我们来写代码吧。
template <typename Ty>
struct my_less0
{
bool operator () (){
return num <5;
}
};
需求变动:我们要可以传threshold怎么办呢,那么这就是 binary_function(2个参数)
我们来写代码吧。
#include<iostream>
#include<algorithm>
#include<vector>
#include<iterator>
using namespace std;
template <typename Ty>
bool my_less(Ty i){
return i < 5;
}
template <typename Ty>
struct my_less1
{
Ty threshold;
my_less1(Ty i):threshold(i){}
bool operator () (Ty num){
return num <threshold;
}
};
int main(int argc,char** argv){
int a[] = {1,2,3,4,5,6,7,8,9,10};
vector<int> vec(a,a+10);
cout<<count_if(vec.begin(),vec.end(),my_less<int>)<<endl;
int x = 8;
cout<<count_if(vec.begin(),vec.end(),my_less1<int>(x))<<endl;
}
我们经常什么地方用到仿函数呢
1.排序
比较成绩(这是一段很久之前写的代码),这段代码并没有使用仿函数,那么我们如何把这段代码改成使用仿函数的呢?
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct E{
char name[100];
int age;
int score;
bool operator < (const E &b) const{ //重定义小于运算符号
if(score!=b.score) return b.score<score;
int tmp=strcmp(name,b.name);
if(tmp!=0) return tmp>0;
else return b.age<age;
}
}buf[1000];
int main()
{
cout<<"请输入要比较的学生的人数:"<<endl;
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>buf[i].name>>buf[i].age>>buf[i].score;
}
sort(buf,buf+n);
cout<<"学生成绩排名比较为:"<<endl;
for(int i=0;i<n;i++)
{
cout<<buf[i].name<<" "<<buf[i].age<<" "<<buf[i].score<<endl;
}
return 0;
}
这样改一下就可以使用仿函数了
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<iterator>
#include<set>
using namespace std;
struct student {
string name;
int score;
student(string n,int s) :name(n),score(s) {}
};
//定义仿函数排序
struct studentSort {
bool operator ()(const student& a,const student& b)const {
if (a.score != b.score) return a.score > b.score;
int tmp = strcmp(a.name.c_str(), b.name.c_str());
if (tmp != 0) return tmp < 0;
else return false;
}
};
int main() {
typedef set<student,studentSort> studentsSet;
studentsSet students;
student s1("zhangsan",80);
student s2("alice",70);
student s3("bob", 90);
student s4("lisi", 90);
students.insert(s1);
students.insert(s2);
students.insert(s3);
students.insert(s4);
studentsSet::const_iterator iter;
for (iter = students.begin(); iter != students.end(); iter++) {
cout << iter->name << " " << iter->score << endl;
}
return 0;
}
- 这里的struct studentSort(排序方法)可以和struct student(数据)分离,并且通过typedef set<student,studentSort> studentsSet可以实现数据与不同的排序方式组合。
- 自增加之类的操作
这里有个之前的代码:
https://www.cnblogs.com/cyssmile/p/12790430.html
#include<iostream>
#include<iterator>
#include<vector>
#include<algorithm>
using namespace std;
template <typename T>
class AddValues{
private:
T val;
public:
AddValues(T j):val(j){}
void operator()(int& i){
cout<<i + val<<endl;
i += val;
}
};
int main(int argc, char** argv){
vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
int x =2;
for_each(vec.begin(),vec.end(),AddValues<int>(x));
cout<<endl;
copy(vec.begin(),vec.end(),ostream_iterator<int>(cout, " "));
}
当然要注意 仿函数都是传值,此类算法一般不会改变参数
所以特殊需求可以传引用或者指针
原文链接: https://www.cnblogs.com/cyssmile/p/12791302.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;
也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/344925
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!