I’ve run into a speedbump while using the STL with what seems like a normal scenario, simplified here:
class Person {
string Name;
int Age;
};
vector<Person> people;
AddPeople(people);
string s("Bob");
find(people.begin(), people.end(), s);
Unfortunately find
wants to compare the entire class.
Is there a better or more appropriate way to do this the “STL way”? The suggested questions weren’t helpful, but I managed to find a couple of related questions but no direct solution.
There’s some potential work-arounds:
Forgo find
altogether (cluttered, but could be refactored):
bool bBob = false; for (UINT i = 0; i < people.size(); i++) { if (people[i].Name == s) bBob = true; break; }
Provide conversion operator (implicit conversion doesn’t work; explicit can’t be used in find
):
class Person { string Name; int Age; operator string() {return Name;} };
Person b ("Bob", 99); string s ("Bob"); b == s; //doesn’t work string(b) == s; //works, but no good for find()
Define a standalone equality operator (simple, effective, but globally exposed):
BOOL operator==(Person l, string r) { return l.Name == r; }
Define a member equality operator (makes comparison order dependent; object must be first):
class Person { string Name; int Age; bool operator==(string s) {return Name == s;} };
Person b ("Bob", 99); string s ("Bob"); b==s; //works s==b; //doesn’t work, but not a problem for find()
It looks like #4 is the best candidate, but none seem ideal or feel “STL”, and some have problems.
Return value The find() function returns an iterator that points to the val in the specified range. If the value is not found, then it returns an iterator to the last of the array or vector.
You use std::find from <algorithm> , which works equally well for std::list and std::vector . std::vector does not have its own search/find function. Note that this works for built-in types like int as well as standard library types like std::string by default because they have operator== provided for them.
Finding an element in vector using STL Algorithm std::find() Basically we need to iterate over all the elements of vector and check if given elements exists or not. This can be done in a single line using std::find i.e. std::vector<int>::iterator it = std::find(vecOfNums.
Is there a better or more appropriate way to do this the “STL way”?
You can use std::find_if
(powered by C++11 lambdas):
std::string name = "Bob";
// ...
std::find_if(std::begin(people), std::end(people),
[&] (Person const& p) { return p.Name == name; }
Notice, that calling it "STL way" is inappropriate. This is the C++ Standard Library, not the STL ("Standard Template Library"). The STL served as a strong inspiration for the Containers and Algorithms Library of the C++ Standard Library, but the two things are not the same. See this Q&A on StackOverflow for further information.
EDIT:
Since you are using a compiler that does not support lambdas, you can define your own functor predicate:
struct person_has_name
{
person_has_name(std::string const& n) : name(n) { }
bool operator () (Person const& p) { return p.Name == name; }
private:
std::string name;
};
And use it with std::find_if
this way:
std::string name = "Bob";
// ...
std::find_if(people.begin(), people.end(), person_has_name(name));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With