範圍 - 超過子範圍
使用基於範圍的迴圈,你可以通過生成符合基於範圍的 for 迴圈的代理物件來迴圈遍歷給定容器或其他範圍的子部分。
template<class Iterator, class Sentinel=Iterator>
struct range_t {
Iterator b;
Sentinel e;
Iterator begin() const { return b; }
Sentinel end() const { return e; }
bool empty() const { return begin()==end(); }
range_t without_front( std::size_t count=1 ) const {
if (std::is_same< std::random_access_iterator_tag, typename std::iterator_traits<Iterator>::iterator_category >{} ) {
count = (std::min)(std::size_t(std::distance(b,e)), count);
}
return {std::next(b, count), e};
}
range_t without_back( std::size_t count=1 ) const {
if (std::is_same< std::random_access_iterator_tag, typename std::iterator_traits<Iterator>::iterator_category >{} ) {
count = (std::min)(std::size_t(std::distance(b,e)), count);
}
return {b, std::prev(e, count)};
}
};
template<class Iterator, class Sentinel>
range_t<Iterator, Sentinel> range( Iterator b, Sentinal e ) {
return {b,e};
}
template<class Iterable>
auto range( Iterable& r ) {
using std::begin; using std::end;
return range(begin(r),end(r));
}
template<class C>
auto except_first( C& c ) {
auto r = range(c);
if (r.empty()) return r;
return r.without_front();
}
現在我們可以做到:
std::vector<int> v = {1,2,3,4};
for (auto i : except_first(v))
std::cout << i << '\n';
並列印出來
2
3
4
請注意,for
迴圈的 for(:range_expression)
部分中生成的中間物件將在 for
迴圈開始時到期。