HC4*_*ica 54 c++ foreach range c++11 std-pair
我刚刚发现,在某一点上,C++ 11草案具有std::begin
/ std::end
重载std::pair
,允许将一对迭代器视为适合在基于范围的for循环中使用的范围(N3126,第20.3.5.5节),但这有自从被删除.
有谁知道为什么它被删除了?
我发现删除非常不幸,因为似乎没有其他方法可以将一对迭代器视为范围.确实:
std::pair
没有开始/结束成员函数std::pair<T, U>
是namespace stdstd::begin
/ std::end
为std::pair
自己std::begin
/ std::end
for std::pair
(因为专业化必须是部分的,而且不允许使用函数)还有其他一些我失踪的方式吗?
sel*_*tze 41
我认为Alisdair Meredith 的2009年论文"Pairs not not good range"至少是答案的一部分.基本上,许多算法返回的迭代器对实际上并不保证是有效范围.pair<iterator,iterator>
由于这个原因,似乎他们从for-range循环中删除了支持.但是,提出的解决方案尚未完全采用.
如果您确定某些迭代器实际上代表了一个有效范围,那么您可以将它们包装成一个提供begin()/ end()成员函数的自定义类型:
template<class Iter>
struct iter_pair_range : std::pair<Iter,Iter> {
iter_pair_range(std::pair<Iter,Iter> const& x)
: std::pair<Iter,Iter>(x)
{}
Iter begin() const {return this->first;}
Iter end() const {return this->second;}
};
template<class Iter>
inline iter_pair_range<Iter> as_range(std::pair<Iter,Iter> const& x)
{ return iter_pair_range<Iter>(x); }
int main() {
multimap<int,int> mm;
...
for (auto& p : as_range(mm.equal_range(42))) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
(另)
我同意这有点蠢.返回有效范围的函数(如equal_range)应该使用适当的返回类型.我们必须通过as_range
上述方式手动确认这一点,这有点令人尴尬.
小智 8
你可以用boost::make_iterator_range
.它用begin()
和end()
方法构造一个iterator_range .
boost::make_iterator_range
可以接受std::pair
迭代器.
使用c ++ 11优化扩展上述答案:
#include <utility>
template<class Iter>
struct range_t : public std::pair<Iter, Iter> {
using pair_t = std::pair<Iter, Iter>;
range_t(pair_t&& src)
: std::pair<Iter, Iter>(std::forward<pair_t>(src))
{}
using std::pair<Iter, Iter>::first;
using std::pair<Iter, Iter>::second;
Iter begin() const { return first; }
Iter end() const { return second; }
};
template<class Iter>
range_t<Iter> range(std::pair<Iter, Iter> p) {
return range_t<Iter>(std::move(p));
}
template<class Iter>
range_t<Iter> range(Iter i1, Iter i2) {
return range_t<Iter>(std::make_pair(std::move(i1), std::move(i2)));
}
// TEST:
#include <iostream>
#include <set>
using namespace std;
int main() {
multiset<int> mySet { 6,4,5,5,5,3,3,67,8,89,7,5,45,4,3 };
cout << "similar elements: ";
for (const auto&i : range(mySet.lower_bound(5), mySet.upper_bound(10))) {
cout << i << ",";
}
cout << "\n";
int count = 0, sum = 0;
for (const auto& i: range(mySet.equal_range(5)))
{
++count;
sum += i;
}
cout << "5 appears " << count << " times\n"
<< "the sum is " << sum << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)