範囲(2つのイテレータのペア)がある場合、生の配列やコンテナではなく、範囲を使用する「foreach」ループを作成する方法があります。
このようなもの:
auto rng = std::equal_range(v.begin(),v.end(),1984);
for(const auto& elem: rng) {
// ...
}
によると、ペア範囲アクセスが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の論文によると、アルゴリズムについて、
mismatch
partition_copy
異なる範囲からのイテレータのペアを返します。minmax
イテレータではない可能性のあるオブジェクトのペアを返します。イテレータがある場合は、範囲を形成する保証はありません。minmax_element
範囲を返すことができますが、逆の範囲を返すこともできます(たとえば、逆にソートされた範囲では;minmax_element
を返します。{prev(last), first}
equal_range
範囲を返すことが保証されています。ドキュメントequal_range
によると、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.
イテレータのペアを取り、それぞれ1番目と2番目のイテレータを返す関数を定義begin
してください。end
#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;
}
}
std::equal_range
返されるのは単にstd::pairです。この規格は、そのようなことを繰り返すための方法をカバーしていません。
あなたが読みたいと思うかもしれないのは、Alexandrescuの「Iteratorsmustgo」プレゼンテーションです。これがビデオです。Rangesを使用してコンテナーを反復処理するためのよりエレガントな方法に関する優れた読み物。
範囲は彼のLokiライブラリに実装されています。