如果我有范围(一对2迭代器)是否有一种方法来为该使用范围写入“for each”循环,而不是原始数组或容器。基于范围循环工作的范围
事情是这样的:
auto rng = std::equal_range(v.begin(),v.end(),1984);
for(const auto& elem: rng) {
// ...
}
如果我有范围(一对2迭代器)是否有一种方法来为该使用范围写入“for each”循环,而不是原始数组或容器。基于范围循环工作的范围
事情是这样的:
auto rng = std::equal_range(v.begin(),v.end(),1984);
for(const auto& elem: rng) {
// ...
}
根据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
保证返回一系列你知道哪些函数返回无效范围吗?我的意思是在标准,而不是用户垃圾:P – NoSenseEtAl 2013-03-20 18:38:06
@NoSenseEtAl好问题,见上文。 – ecatmur 2013-03-21 10:29:40
我不认为它会像开箱作为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.
我会说你可以定义begin
和end
函数,采用这对迭代器并分别返回第一个和第二个函数。
什么std::equal_range
回报标准不包括任何方法来迭代这些事情
你可能想要阅读的是Alexandrescu的"Iterators must go"演示文稿Here is the video。关于更多el的优秀阅读egant使用范围迭代容器的方法。
范围在他的Loki库中执行。
范围是在boost中实现的,并且它们正在std的路上,所以任何想要使用它们的人都应该使用boost – NoSenseEtAl 2013-03-20 18:21:02
我知道Boost.Range,但是我没有很好地看它,不确定如果它们与Alexandrescu的Ranges相同。这就是为什么我不建议Boost.Range。你确定他们是一样的吗? – 2013-03-20 18:22:39
afaik不,但idk的区别,如果iirc corectly提升/ std范围只是对iter ....但我真的不知道细节... – NoSenseEtAl 2013-03-20 18:41:51
#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;
}
}
你可以使用boost吗? – inf 2013-03-20 17:18:43
如果你可以使用boost,boost有一个范围迭代器。 – OmnipotentEntity 2013-03-20 17:19:16
是的,我可以和我做:) <3 boost – NoSenseEtAl 2013-03-20 17:23:42