You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中如何通过模板传递布尔过滤函数实现数据过滤?

C++中通过模板传递过滤函数实现数据过滤

我尝试用布尔函数过滤数据,写了一段有错误的代码,想知道C++里能不能像Lua那样通过模板传递过滤函数参数来实现这个功能,以下是我的错误代码:

#include <iostream>
#include <cstring>
#include <vector>

using namespace std;

class Person
{
    private:
    
    string name;
    int age;
    double height;
    char gender;
    
    public:
    
    Person(string name,int age,double height,char gender);
    
    string getName() {return name};
    int getAge() { return age; }
    double getHeight() { return height; }
    char getGender() { return gender; }
}

Person::Person(string name,int age, double height,char gender)
{
    this->name = name;
    this->age = age;
    this->height = height;
    this->gender = gender;
}

bool IsName(Person p, string name)
{
    if(p.getName == name) return true;
    return false;
}

int IsAge(Person p, int age)
{
    if(p.getAge == age) return true;
    return false;
}

double IsHeight(Person p, double height)
{
    if(p.getHeight == height) return true;
    return false;
}

bool IsGender(Person p, char gender)
{
    if(p.getGender == gender) return true;
    return false;
}

class Group
{
    public:
    
    vector <Person> People;
    
    int getPersonCount(bool (*filter)(int));
}

template <class T>

int Group::getPersonCount(bool (*filter)(T), T t)
{
    int ct = 0;
    
    for(int i=0;i<People.size();i++) if(People[i],filter(t)) ct++;
    
    return ct;
}

int main()
{
    Person p1("Alice",24,1.80,'F'), p2("Bob",18,1.60,'M'), p3("Charlie",30,1.70,'M');
    
    Group g;
    
    g.People.push_back(p1);
    g.People.push_back(p2);
    g.People.push_back(p3);
    
    cout<<g.getPersonCount(&IsName,"Alice");

    return 0;
}

代码中的错误点

  • Person类语法错误:
    1. getName()函数末尾缺少分号,应改为string getName() {return name;};
    2. Person类定义结束后必须加;,这是C++类定义的语法要求
  • 成员函数调用错误:所有过滤函数中调用Person的getter方法时未加括号,比如p.getName == name 应改为p.getName() == name
  • 返回值类型错误:IsAge和IsHeight的返回值类型应为bool,而非int和double
  • 参数效率问题:过滤函数的Person参数应使用const引用,避免不必要的对象拷贝
  • 函数声明与实现不匹配:
    1. Group类中声明的getPersonCount参数为bool (*filter)(int),与模板实现的参数完全不兼容
    2. 模板函数的循环判断逻辑错误:if(People[i],filter(t)) 应改为if(filter(People[i], t)),过滤函数需要同时接收Person对象和目标值
  • 函数指针类型不匹配:IsName的签名是bool(Person, string),但模板期望的是bool(T),类型无法适配

修正后的实现代码

要实现通过模板传递过滤函数的功能,需要让模板适配过滤函数的签名,以下是修正后的完整代码:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Person
{
private:
    string name;
    int age;
    double height;
    char gender;

public:
    // 使用初始化列表简化构造函数
    Person(string name, int age, double height, char gender)
        : name(std::move(name)), age(age), height(height), gender(gender) {}

    // 标记getter为const成员函数,保证能被const引用调用
    string getName() const { return name; }
    int getAge() const { return age; }
    double getHeight() const { return height; }
    char getGender() const { return gender; }
};

// 过滤函数:用const引用避免拷贝,提升效率
bool IsName(const Person& p, const string& name)
{
    return p.getName() == name;
}

bool IsAge(const Person& p, int age)
{
    return p.getAge() == age;
}

bool IsHeight(const Person& p, double height)
{
    return p.getHeight() == height;
}

bool IsGender(const Person& p, char gender)
{
    return p.getGender() == gender;
}

class Group
{
public:
    vector<Person> People;

    // 模板函数:适配不同类型的过滤目标值
    template <typename T>
    int getPersonCount(bool (*filter)(const Person&, const T&), const T& target)
    {
        int count = 0;
        // 用范围for循环简化遍历
        for (const auto& person : People)
        {
            if (filter(person, target))
            {
                count++;
            }
        }
        return count;
    }
};

int main()
{
    Person p1("Alice", 24, 1.80, 'F'), p2("Bob", 18, 1.60, 'M'), p3("Charlie", 30, 1.70, 'M');
    Group g;
    g.People.push_back(p1);
    g.People.push_back(p2);
    g.People.push_back(p3);

    cout << "名为Alice的人数:" << g.getPersonCount(&IsName, "Alice") << endl;
    cout << "年龄为18的人数:" << g.getPersonCount(&IsAge, 18) << endl;
    cout << "性别为M的人数:" << g.getPersonCount(&IsGender, 'M') << endl;

    return 0;
}

额外优化:使用Lambda表达式

在C++11及以后的版本中,用Lambda表达式可以更简洁地实现过滤,不需要单独定义过滤函数:

// 在main函数中直接使用Lambda实现自定义过滤
cout << "身高大于1.7的人数:" << g.getPersonCount(
    [](const Person& p, double h) { return p.getHeight() > h; },
    1.7
) << endl;

结论

C++完全可以实现通过模板传递过滤函数的功能,核心是让模板适配过滤函数的参数类型,同时注意函数签名匹配、避免不必要的拷贝。Lambda表达式则能进一步简化代码,实现更灵活的过滤逻辑。

内容的提问来源于stack exchange,提问作者Давид Желев

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 23:45:32