如果我有範圍(一對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