Is it possible to send part of vector to vector to function?

I want to see if it is possible to pass part of a vector to a function so that it appears as a normal vector to a function. More importantly, I want this to be done in O (1), constant time. I don't want to iterate over the vector to create a new one. In fact, I also want the size of the new vector to change to 40 in the following example.

void func(vector <int> &v){

    //calling index 10  to 50 of v
    func(v[10..50])
}

      

+3


source to share


3 answers


Use iterators as parameters to a range based function and navigate to the desired range. Your code in the function will become

funcWithRange(v.cbegin()+10, v.cbegin()+50);

      

with function signature



void funcWithRange(std::vector<int>::const_iterator first, std::vector<int>::const_iterator last)

      

This could be generalized by making this function template with the element type vector

as its template parameter, or even more for any container that supports this type of range iteration. As noted in the comments, <algorithm>

has many examples of this pattern.

std::distance(first, last);

will return the desired resized size. I don't think you can come close to your requirements without a physical copy.

+5


source


If you have a vector of 100 elements

std::vector<int> v(100);

      

and you want to call void f(std::vector<int> v)

with the first 10 elements, just call the function like



f({v.cbegin(), v.cbegin() + 10});

      

This will construct a new vector from two iterators (by copying the elements) and pass the new vector to f

.

+1


source


There is a means to achieve something like this that is proposed for inclusion in the standard C++

. It's called a span

, and it somehow works like a vector.

#include <gsl/span>

void func(gsl::span<int> sp)
{
    for(auto& i: sp)
        std::cout << i << '\n';
}

int main()
{
    // ...

    std::vector<int> v(100);

    // put something in the vector (numbers 0 - 99)
    std::iota(std::begin(v), std::end(v), 0);

    // wrap the container in a span
    auto sp = gsl::make_span(v);

    // send parts of it to functions
    func(sp.subspan(10, 50));
}

      

The implementation span

can be found here: https://github.com/Microsoft/GSL

This is the recommended way of passing continuous containers in Best Practices by Bjarne Stroustup and Herb Sutter.

The guides can be found here: CppCoreGuidelines.md

+1


source







All Articles