Подтвердить что ты не робот

С++ 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, как я могу сделать что-то вроде этого?

4b9b3361

Ответ 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, вы можете просто создать объект функции самостоятельно. Сделайте оператор типа и перегрузки().