С++ std:: find с пользовательским компаратором
Это в основном то, что я хочу сделать:
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);
Но std::find
не работает, к сожалению. Поэтому, используя только STL, как я могу сделать что-то вроде этого?
Ответы
Ответ 1
На основе ваших комментариев вы, вероятно, ищете следующее:
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*"));
Ответ 2
Функция, которую вам нужно использовать, такова: std::find_if
, потому что std::find
не выполняет функцию сравнения.
Но тогда std::find_if
не принимает значения. Вы пытаетесь передать значение и сравнить оба, что меня сбивает с толку. В любом случае, посмотрите документацию. См. Разницу в использовании:
auto it1 = std::find(strings.begin(), strings.end(), "hell*");
auto it2 = std::find_if(strings.begin(), strings.end(), special_compare);
Надеюсь, что это поможет.
Ответ 3
Вам понадобится std::find_if()
, что неудобно использовать, если вы не используете компилятор С++ 11. Потому что тогда вам не нужно жестко кодировать значение для поиска в некоторой функции компаратора или реализовать объект-функтор, но может сделать это в выражении лямбда:
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*");
});
Затем вы пишете match_wildcard() где-нибудь.
Ответ 4
Поскольку никто не упомянул std::bind
, я предлагаю этот
#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*"));
Ответ 5
С С++ 11 lambdas:
auto found = find_if(strings.begin(), strings.end(), [] (const std::string& s) {
return /* you can use "hell*" here! */;
});
Если вы не можете использовать lambdas С++ 11, вы можете просто создать объект функции самостоятельно. Сделайте оператор типа и перегрузки().