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

如何在存储Employee类对象的std::vector中按成员查找并删除元素?

问题:使用std::find_if删除vector中指定名称的Employee元素

我有一个存储Employee类对象的std::vector,每个Employee包含std::string_view类型的成员m_name和int类型的成员m_time,目标是删除vector中包含指定名称的元素。尝试用std::find_if算法,但自定义布尔函数和lambda表达式都出现匹配错误。

原代码

#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <string_view>
#include <string>

//Track employees and time worked
class Employee
{
public:
    std::string_view m_name{};
    int m_time{};

    Employee(std::string_view name, int time)
    :m_name{name}, m_time {time}
    {
    }
};

void printEmployees(const std::vector<Employee>& employee)
{
    for (const auto& a: employee)
    {
        std::cout << a.m_name << " " << a.m_time << "\n";
    }

}

bool findEmployee(Employee &employee, std::string_view myWord)
{
    if (myWord == employee.m_name)
        return true;

    else
        return false;
}



int main()
{
    std::vector<Employee> employee{   {"Daniel Ramirez", 14},
                                      {"Marta Martinez", 55},
                                      {"Joseph Martin", 100}
                                           };


    // erase the element that contains "Marta Martinez" on the array:
    std::string myWord{"Marta Martinez"};

    // auto it { std::find_if(employee.begin(),employee.end(), findEmployee(employee, myWord) ) };


    //using lambda
    auto it { std::find_if(employee.begin(),employee.end(),   [](const Employee& employee, std::string_view myWord)
                                                                                    {
                                                                                        if (myWord == employee.m_name)
                                                                                            return true;

                                                                                        else
                                                                                            return false;
                                                                                    }) };

    if (it == employee.end())           // check if element was found
        std::cout << "Element wasn't found";


    //printEmployees(employee);
    return 0;
}

报错信息

error: no matching function for call to object of type '(lambda at /Users/danielramirez/CLionProjects/test/main.cpp:81:63)'
        if (__pred(*__first))

错误分析与修正

1. Lambda表达式的核心问题

std::find_if要求第三个参数是单参数谓词:它会遍历vector的每个元素,仅把当前遍历的单个元素传递给谓词,谓词返回bool表示是否匹配。你写的lambda有两个参数,std::find_if无法传递第二个参数,因此出现参数不匹配错误。

解决方法:通过捕获外部的myWord变量,让lambda只接收一个Employee类型的参数:

// 修正后的lambda写法
auto it = std::find_if(employee.begin(), employee.end(),
    [&myWord](const Employee& emp) {
        return emp.m_name == myWord;
    });
  • [&myWord]表示按引用捕获外部的myWord变量,lambda内部可直接使用该变量
  • lambda仅接受一个const Employee&参数,完全符合std::find_if的要求

2. 自定义函数的问题与解决

你写的findEmployee是双参数函数,不符合std::find_if对单参数谓词的要求。可以通过std::bind绑定固定参数来适配:

#include <functional> // 必须包含此头文件

// 用bind把myWord绑定为第二个固定参数
auto it = std::find_if(employee.begin(), employee.end(),
    std::bind(findEmployee, std::placeholders::_1, myWord));
  • std::placeholders::_1表示第一个参数由std::find_if自动传递(即遍历的Employee元素),第二个参数固定为myWord

3. 完成删除操作

找到目标元素的迭代器后,需要调用vector::erase完成删除:

if (it != employee.end()) {
    employee.erase(it);
    std::cout << "元素已删除\n";
} else {
    std::cout << "未找到元素\n";
}

完整修正后的代码

#include <iostream>
#include <vector>
#include <algorithm>
#include <string_view>
#include <string>

class Employee
{
public:
    std::string_view m_name{};
    int m_time{};

    Employee(std::string_view name, int time)
        : m_name{name}, m_time{time}
    {
    }
};

void printEmployees(const std::vector<Employee>& employees)
{
    for (const auto& emp : employees)
    {
        std::cout << emp.m_name << " " << emp.m_time << "\n";
    }
}

int main()
{
    std::vector<Employee> employees{
        {"Daniel Ramirez", 14},
        {"Marta Martinez", 55},
        {"Joseph Martin", 100}
    };

    std::string targetName{"Marta Martinez"};

    // 使用lambda查找目标元素
    auto it = std::find_if(employees.begin(), employees.end(),
        [&targetName](const Employee& emp) {
            return emp.m_name == targetName;
        });

    if (it != employees.end()) {
        employees.erase(it);
        std::cout << "已删除员工:" << targetName << "\n";
    } else {
        std::cout << "未找到员工:" << targetName << "\n";
    }

    printEmployees(employees);
    return 0;
}

额外注意点

  • 你的Employee类用std::string_view存储名称,要确保string_view指向的字符串生命周期足够长(比如字符串字面量、全局字符串,或长期存在的std::string),否则会出现悬空指针导致未定义行为。
  • 如果需要删除多个匹配的元素,建议使用erase-remove惯用法:
    employees.erase(
        std::remove_if(employees.begin(), employees.end(),
            [&targetName](const Employee& emp) {
                return emp.m_name == targetName;
            }),
        employees.end()
    );
    

内容的提问来源于stack exchange,提问作者tadm123

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 06:47:03