2013-03-20 117 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; 
    } 
}