-1

Is it possible to loop over sub range using range based for loop ?

std::vector <std::string> inputs={"1","abaaaa","abc","cda"};
 
for (auto &it : new_vector(inputs.begin()+1, inputs.end()))
{
    // …
}
Enlico
  • 23,259
  • 6
  • 48
  • 102
a k
  • 531
  • 5
  • 15

3 Answers3

1

You could use Boost's iterator_range:

for (auto &it : boost::make_iterator_range(inputs.begin()+1, inputs.end()))
{
    cout << it << endl;
}

demo

Alternatively you could write your own wrapper.

krzaq
  • 16,240
  • 4
  • 46
  • 61
1

Unfortunately, there is no such thing in the C++ standard library. However, you can define your own wrapper like this (requires at least C++ 11 - which should not be problem in 2021):

template<typename Iter>
struct range
{
    Iter b, e;
    Iter begin() const { return b; }
    Iter end() const { return e; }
};
template<typename T>
auto slice(const T& c, std::size_t from, std::size_t to = -1) -> range<decltype(c.begin())>
{
    to = (to > c.size() ? c.size() : to);
    return range<decltype(c.begin())>{c.begin() + from, c.begin() + to};
}

And then you can use it:

std::vector<int> items(100);
// Iterates from 4th to 49th item
for (auto x: slice(items, 4, 50))
{
    
}
// Iterates from 15th to the last item
for (auto x: slice(items, 15))
{
    
}
1

tl;dr

Long story short, you #include <range/v3/view/subrange.hpp> and change your new_vector to ranges::subrange. And that's it. Demo on Compiler Explorer.

So

Given the name you imagine for this function, new_vector, maybe you think you need the entity on the right of : to be a std::vector or at least some type of container.

If that's the case, then change your mind, it's not needed. All that : wants from its "right hand side" is that it have begin and end defined on them, member or non member. For instance, this compiles and runs just fine:

struct A {};
int* begin(A);
int* end(A);

struct B {
    int* begin();
    int* end();
};

int main()
{
    for (auto it : A{}) {}
    for (auto it : B{}) {}
}
Enlico
  • 23,259
  • 6
  • 48
  • 102