2013-03-20 110 views
7

如果我有范围(一对2迭代器)是否有一种方法来为该使用范围写入“for each”循环,而不是原始数组或容器。基于范围循环工作的范围

事情是这样的:

auto rng = std::equal_range(v.begin(),v.end(),1984); 
for(const auto& elem: rng) { 
    // ... 
} 
+1

你可以使用boost吗? – inf 2013-03-20 17:18:43

+1

如果你可以使用boost,boost有一个范围迭代器。 – OmnipotentEntity 2013-03-20 17:19:16

+0

是的,我可以和我做:) <3 boost – NoSenseEtAl 2013-03-20 17:23:42

回答

13

根据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

  • mismatchpartition_copy回报一对来自不同范围的迭代器;
  • minmax返回一对可能不是迭代器的对象,如果它们不能保证它们形成范围;
  • minmax_element可以在反向排序范围minmax_element返回一个范围,但它也可以返回一个反向范围(例如将返回{prev(last), first};
  • equal_range保证返回一系列
+0

你知道哪些函数返回无效范围吗?我的意思是在标准,而不是用户垃圾:P – NoSenseEtAl 2013-03-20 18:38:06

+0

@NoSenseEtAl好问题,见上文。 – ecatmur 2013-03-21 10:29:40

2

我不认为它会像开箱作为equal_range的返回一对迭代的同时,将根据documentation周期超过范围是:

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. 

我会说你可以定义beginend函数,采用这对迭代器并分别返回第一个和第二个函数。

0

什么std::equal_range回报标准不包括任何方法来迭代这些事情

你可能想要阅读的是Alexandrescu的"Iterators must go"演示文稿Here is the video。关于更多el的优秀阅读egant使用范围迭代容器的方法。

范围在他的Loki库中执行。

+0

范围是在boost中实现的,并且它们正在std的路上,所以任何想要使用它们的人都应该使用boost – NoSenseEtAl 2013-03-20 18:21:02

+0

我知道Boost.Range,但是我没有很好地看它,不确定如果它们与Alexandrescu的Ranges相同。这就是为什么我不建议Boost.Range。你确定他们是一样的吗? – 2013-03-20 18:22:39

+0

afaik不,但idk的区别,如果iirc corectly提升/ std范围只是对iter ....但我真的不知道细节... – NoSenseEtAl 2013-03-20 18:41:51

0
#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; 
    } 
}