如果我有范围(一对2个迭代器),那么有一种方法可以为该使用范围编写“for each”循环,而不是原始数组或容器。
这样的事情:
auto rng = std::equal_range(v.begin(),v.end(),1984);
for(const auto& elem: rng) {
// ...
}
答案 0 :(得分:14)
根据Why was pair range access removed from C++11?,您可以使用适配器,例如接受回答的as_range
,boost::make_iterator_range
,或自己编写:
template<typename It> struct range {
It begin_, end_;
It begin() const { return begin_; }
It end() const { return end_; }
};
template<typename It> range<It> as_range(const std::pair<It, It> &p) {
return {p.first, p.second};
}
auto rng = std::equal_range(v.begin(),v.end(),1984);
for(const auto& elem: as_range(rng))
...
一般不适用的原因是每Alastair Meredith's paper个算法
mismatch
和partition_copy
返回来自不同范围的一对迭代器; minmax
返回一对可能根本不是迭代器的对象,如果它们不存在则无法保证它们形成范围; minmax_element
可以返回一个范围,但也可以返回反转范围(例如,在反向排序的范围minmax_element
将返回{prev(last), first}
; equal_range
保证返回范围。答案 1 :(得分:2)
我不认为它会像开箱即用那样工作,因为equal_range
返回一对迭代器,而documentation的for循环范围是:
The begin_expr and end_expr are defined to be either:
If (__range) is an array, then (__range) and (__range + __bound), where __bound is the array bound
If (__range) is a class and has either a begin or end member (or both), then begin_expr is __range.begin() and end_expr is __range.end();
Otherwise, begin(__range) and end(__range), which are found based on argument-dependent lookup rules with std as an associated namespace.
我想你可以定义begin
和end
函数来获取迭代器对并分别返回第一个和第二个函数。
答案 2 :(得分:1)
#include <vector>
#include <algorithm>
#include <iostream>
template <typename I>
struct range_adapter {
std::pair<I, I> p;
range_adapter(const std::pair<I, I> &p) : p(p) {}
I begin() const { return p.first; }
I end() const { return p.second; }
};
template <typename I>
range_adapter<I> in_range(const std::pair<I, I> &p)
{
return range_adapter<I>(p);
}
int main()
{
std::vector<int> data { 1, 2, 2, 3, 3, 3, 4 };
auto r = std::equal_range(data.begin(), data.end(), 2);
for (const auto &elem : in_range(r))
{
std::cout << elem << std::endl;
}
}
答案 3 :(得分:0)
std::equal_range
返回的只是一个std ::对。该标准没有涵盖迭代这些事情的任何方法。
您可能想要阅读的内容是Alexandrescu的"Iterators must go"演示文稿。 Here is the video。阅读更优雅的方法,使用Ranges迭代容器。
范围在他的Loki库中实现。