Допустим, у меня есть вектор строк, и я хочу, чтобы найти все строки, которые начинаются с 'a'
, так что я могу это сделать:станд :: equal_range с лямбда
struct cmp {
bool operator()(const std::string &s, char c) const { return s.front() < c; }
bool operator()(char c, const std::string &s) const { return s.front() < c; }
};
std::vector<std::string> strings;
...
std::sort(strings.begin(), strings.end());
auto range = std::equal_range(strings.begin(), strings.end(), 'a', cmp{});
...
Этот метод подвержен ошибкам, так как легко ошибиться (например, я думаю, что это должно быть c < s.front()
во втором методе) и имеет дублирование кода.
Так можно ли реализовать функцию сравнения с общей лямбдой вместо структуры с помощью 2 методов?
Более общий вопрос, почему значение для сравнения должно быть принят в качестве аргумента std::lower_bound
, std::upper_bound
и std::equal_range
, когда она легко может быть захвачена лямбда или передается в структуре сравнения, а затем этот вопрос не будет там вообще?
Как это могло бы работать, если std::equal_range
не требовало бы стоимости?
struct cmp {
cmp(char lc) : c(lc) {}
bool operator()(const std::string &s) const { return s.front() < c; }
char c;
};
std::vector<std::string> strings;
...
std::sort(strings.begin(), strings.end());
auto range = std::equal_range(strings.begin(), strings.end(), cmp{'a'});
Если вы готовы передать '' a '' вместо '' a'', тогда будет работать лямбда с двумя строками и сравнением их первых символов. В противном случае названный класс с двумя перегрузками выглядит как самое чистое решение для меня. Обратите внимание, что вторая перегрузка, как написано в настоящее время, делает ее сравнение неправильным образом. –
@IgorTandetnik это очевидно, но это может быть не строка, а объект, который отсортирован по его части, поэтому я не хочу создавать целые объекты только для использования в качестве ключа. – Slava
Вы можете использовать 'std :: partition_point'. –