2013-03-20 11 views
7

範囲(2つのイテレータのペア)に、生の配列またはコンテナではなく、その範囲の "for each each"ループを記述する方法があります。範囲を超えてループを処理できる範囲

このような何か:documentationに応じて範囲に渡って、私はそれがequal_rangeとして箱の外にそのように動作するとは思わない

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

ブーストを使用できますか? – inf

+1

ブーストを使用できる場合、ブーストには範囲イテレータがあります。 – OmnipotentEntity

+0

はいいいえ、できます:) <3 boost – NoSenseEtAl

答えて

13

Why was pair range access removed from C++11?ごとに、アダプタを使用できます。受け入れ答えでas_rangeboost::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リターンaは異なる範囲のイテレータのペア。
  • minmaxは、イテレータではないオブジェクトのペアを返します。それらが存在する場合、それらが範囲を形成するという保証はありません。 {prev(last), first}を返します。逆ソート範囲minmax_elementに例えば(
  • minmax_elementは範囲を返すことができますが、それはまた、逆に範囲を返すことができます;。
  • equal_range範囲を返すことが保証されて
+0

どのような関数が無効な範囲を返すか知っていますか?私は標準で、ユーザーの迷惑ではない:P – NoSenseEtAl

+0

@NoSenseEtAl良い質問、上記を参照してください。 – ecatmur

2

をしながら、イテレータのペアを返す、サイクルのためには、次のとおりです。

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関数を定義し、resepectively第一及び第二の1を返すことが言えるでしょう。

0

std::equal_rangeリターンを

あなたが読んでいるかもしれないものは、Alexandrescuのプレゼンテーションです。Here is the video。例えばレンジを使ってコンテナを反復する方法です。

範囲は彼のLokiライブラリで実装されています。

+0

範囲はboostで実装されていますので、stdに向かいますので、使用したい人はboostを使用してください。 – NoSenseEtAl

+0

私はBoost.Rangeを認識していますが、彼らがAlexandrescu's Rangesと同じであれば。だから私はBoost.Rangeを提案しなかった。彼らは同じものだと確信していますか? –

+0

afaik noしかし、iircのcorectly boost/std範囲がちょうどiterのペアであるのならば、idkの違いです...しかし、私は本当に詳細を知りません... – NoSenseEtAl

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; 
    } 
} 
関連する問題