Create a wrapper for which begin () and end () return the correct iterators, and then you can use this as the second argument.
#include <iostream> #include <vector> template< typename Collection > class FromNth { Collection& coll_; size_t offset_; public: FromNth( Collection& coll, size_t offset ) : coll_( coll ), offset_( offset ) { } // will nicely resolve to const_iterator if necessary auto begin() const -> decltype( coll_.begin() ) { return coll_.begin() + offset_; } auto end() const -> decltype( coll_.end() ) { return coll_.end(); } }; template< typename Collection > FromNth<Collection> makeFromNth( Collection& collection, size_t offset ) { return FromNth<Collection>( collection, offset ); } template< typename Collection > auto begin( const FromNth<Collection> & wrapper ) -> decltype( wrapper.begin() ) { return wrapper.begin(); } template< typename Collection > auto end( const FromNth<Collection> & wrapper ) -> decltype( wrapper.end() ) { return wrapper.end(); } int main() { std::vector< int > coll { 2, 3, 5, 7, 11, 13, 17, 19, 23 }; for( auto x : makeFromNth( coll, 1 ) ) { std::cout << x << '\n'; } return 0; }
Note that my fromNth "begin" is undefined behavior if the input size is less than the offset. (If it is equal, then it is clearly defined and starts == end). Therefore, first check the size.
Note. If you are using an updated version of boost, then iterator_range may already provide you with a “collection” that looks like my “FromNth”.
for( auto const& s : boost::make_iterator_range( v.begin() + 1, v.end() ) ) { process( s ); }
Note: the code above worked on CodingGround using C ++ 11 GNU 4.8.3. (This site is very slow, though). From C ++ 14 you will not need the operators → decltype (which are required in C ++ 11 for templates).
Output:
sh-4.3$ g++ -std=c++11 -o main *.cpp sh-4.3$ main 3 5 7 11 13 17 19 23
source share