1

我有 2 个迭代器 range_begin、range_end,它们是我的容器。我需要找到所有以 char 前缀开头的字符串。这是我的代码:

template <typename RandomIt>
pair<RandomIt, RandomIt> FindStartsWith(
RandomIt range_begin, RandomIt 
range_end,char prefix){
auto it=equal_range(range_begin,range_end,prefix,
[prefix](const string& city){return city[0]==prefix;});
return it;}

例如,对于

const vector<string> sorted_strings = {"moscow", "murmansk", "vologda"};
auto it=FindStartsWith(strings.begin(),strings.end(),'m');

我想首先在“莫斯科”上获得迭代器,最后在“摩尔曼斯克”之后获得迭代器。

我收到奇怪的编译器错误。出了什么问题,我该如何解决?我无法编写正确的 lambda 比较器。

4

2 回答 2

2

equal_range需要一个接受两个参数的比较函数;你正在传递一个函数。

异构调用(其中的类型value与范围中的类型元素不同)需要一个比较函数,该函数可以按任意顺序获取这两种类型。lambda 在这种情况下不起作用,因为它只有一个operator()重载。

最后,函数必须执行小于类型的比较,而不是等于。粗略地,equal_range返回从 which 的第一个元素到 which!(element < value)的第一个元素的范围value < element

于 2019-04-14T02:08:59.903 回答
1

您的错误可能是由于strings.begin()和 .end() 没有sorted_。我认为您也不应该使用模板。除了错误,我建议您使用不同的 std 函数。一个更简单的解决方案是使用 foreach:

#include <algorithm>
#include <iterator>
#include <list>
#include <string>
#include <utility>
#include <vector>

typedef std::vector<std::string>::const_iterator RandomIt;

std::vector<std::string> FindStartsWith(RandomIt start, RandomIt end, const char prefix) {
    std::vector<std::string> result;

    std::for_each(start, end, [&](auto city) {
        if (city.front() == prefix) {
          result.push_back(city);
        }
    });

    return result;
}

int main(int argc, char* argv[]) {
    const std::vector<std::string> sorted_strings = { "moscow", "murmansk", "vologda" };
    auto prefix_cities = FindStartsWith(sorted_strings.begin(), sorted_strings.end(), 'm');

    return 0;
}

绝对可以使用重构,但我假设您出于其他原因需要在 FindStartsWith 中实现它......

感谢您的发帖,这教会了我很多关于 equal_range 的知识 :)

于 2019-04-14T02:18:50.763 回答