Reputation: 6272
This is basically what I want to do:
bool special_compare(const string& s1, const string& s2)
{
// match with wild card
}
std::vector<string> strings;
strings.push_back("Hello");
strings.push_back("World");
// I want this to find "Hello"
find(strings.begin(), strings.end(), "hell*", special_compare);
// And I want this to find "World"
find(strings.begin(), strings.end(), "**rld", special_compare);
But std::find
doesn't work like that unfortunately. So using only the STL, how can I do something like this?
Upvotes: 34
Views: 46270
Reputation: 4308
I wanted to have an example with custom class having custom find logic but didn't find any answer like that. So I wrote this answer which uses custom comparator function (C++11) to find an object.
class Student {
private:
long long m_id;
// private fields
public:
long long getId() { return m_id; };
};
Now suppose, I want to find the student
object whose m_id
matches with a given id. I can write std::find_if
like this:
// studentList is a vector array
long long x_id = 3; // local variable
auto itr = std::find_if(studentList.begin(), studentList.end(),
[x_id](Student& std_val)
{ return std_val.getId() == x_id; }
);
if(itr == studentList.end())
printf("nothing found");
Upvotes: 3
Reputation: 74028
Since nobody has mentioned std::bind
yet, I'll propose this one
#include <functional>
bool special_compare(const std::string& s, const std::string& pattern)
{
// match with wild card
}
std::vector<std::string> strings;
auto i = find_if(strings.begin(), strings.end(), std::bind(special_compare, std::placeholders::_1, "hell*"));
Upvotes: 7
Reputation: 171127
Based on your comments, you're probably looking for this:
struct special_compare : public std::unary_function<std::string, bool>
{
explicit special_compare(const std::string &baseline) : baseline(baseline) {}
bool operator() (const std::string &arg)
{ return somehow_compare(arg, baseline); }
std::string baseline;
}
std::find_if(strings.begin(), strings.end(), special_compare("hell*"));
Upvotes: 37
Reputation: 51840
You'll need std::find_if()
, which is awkward to use, unless you're on a C++11 compiler. Because then, you don't need to hardcode the value to search for in some comparator function or implement a functor object, but can do it in a lambda expression:
vector<string> strings;
strings.push_back("Hello");
strings.push_back("World");
find_if(strings.begin(), strings.end(), [](const string& s) {
return matches_wildcard(s, "hell*");
});
Then you write a matches_wildcard() somewhere.
Upvotes: 12
Reputation: 3510
With C++11 lambdas:
auto found = find_if(strings.begin(), strings.end(), [] (const std::string& s) {
return /* you can use "hell*" here! */;
});
If you can't use C++11 lambdas, you can just make a function object yourself. Make a type and overload operator ().
Upvotes: 8
Reputation: 361472
The function you need to use is this : std::find_if
, because std::find
doesn't take compare function.
But then std::find_if
doesn't take value. You're trying to pass value and compare both, which is confusing me. Anyway, look at the documentation. See the difference of the usage:
auto it1 = std::find(strings.begin(), strings.end(), "hell*");
auto it2 = std::find_if(strings.begin(), strings.end(), special_compare);
Hope that helps.
Upvotes: 12