I have a vector
of classes. Each class has two member variables, a name (string) and time spent working (integer).
My goal is simply delete an element of an array that contains a specific name.
I know I cannot use the find()
algorithim, so I'm trying with the find_if()
algorithim.
I'm have tried making my own boolean function, which is not working. So I tried with a lambda function with the same bad results.
Reading the documentation for find_if
. Apparently I need to give it a callable object, like a pointer. But if so, how would I pass my Employee
class, to compare the member function name
of it and also the word that I want to compare it with?
Here's my code:
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <string_view>
#include <string>
//First problem is using class and std::vector
//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:
error: no matching function for call to object of type '(lambda at /Users/danielramirez/CLionProjects/test/main.cpp:81:63)'
if (__pred(*__first))
I know I'm doing something wrong in terms of implementing the 3rd argument of the find_if
algorithm. Any help is really appreciated.
find_if
takes a single-argument lambda. You don't need to pass myWord
into it, you just capture it (using e.g. [&]
- "capture all by reference by default").
[&](const Employee& employee)
{
return myWord == employee.m_name;
}
You can also simplify if (x) return true; else return false;
to just return x;
, as shown.
Then you pass the resulting iterator to employee.erase(it);
(if it's not .end()
) to delete the element.
Or you can use std::erase_if(employee, /*same lambda as a above*/);
oneliner to delete all matches.