C++仿函数(二)为什么使用使用仿函数

考虑以下需求:
统计某个容器中符合规定的元素个数,比如这里规定就是小于某个数(如果有其他需求可以自定义一个仿函数)
来我们来写代码:

#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可以实现数据与不同的排序方式组合。
  1. 自增加之类的操作
    这里有个之前的代码:
    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/12790854.html

原文链接: https://www.cnblogs.com/cyssmile/p/12791302.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    C++仿函数(二)为什么使用使用仿函数

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/344925

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 上午2:57
下一篇 2023年3月2日 上午2:57

相关推荐