I am currently utilizing the range constructor of std::vector
to create another vector of a given subrange.
std::vector<int> myVect { 1, 2, 3, 4 };
std::vector<int> subrangeVector(myVect.begin(), myVect.begin() + 2);
However, this results in the ranged values of myVect being copied and taking up additional memory. This is something that is undesirable when working withing limited memory and/or with very large element types.
How do I construct a subrange of another vector by reference?
A simplified explanation of my objective is as follows:
void fun(std::vector<int> & v) { v.at(0) = 1; }
int main()
{
std::vector<int> myVect { 1, 2, 3, 4 };
std::size_t upperLimit = 5;
std::vector<int> subrangeVector = subrangeView(myVect, upperLimit);
fun(subrangeVector); // so myVect.at(0) == 1
return 0;
}
This would be implemented in many different functions that utilize std::vector
as a parameter. I do not want to pass iterators as discussed here. Assume that I have no control over the function fun
.
A C++ vector is a type which "owns" its memory - it cannot be a "reference type" into another vector's data.
Instead, you will likely find a span useful: A span is a class representing contiguous data in memory - just like a vector; but - it is a "reference type", and it is not owning - just what you wanted to have. It behaves like a vector w.r.t. iteration, operator[]
, and so on.
In your case, you would write:
std::vector<int> myVect { 1, 2, 3, 4 };
auto subrange { std::span{myVect}.subspan(0, 2); }
and then use subrange just as you were planning to with the vector.
PS: This is C++20 code, since C++17 doesn't have spans yet; if you're using earlier C++ versions, use gsl::span
from the Guidelines Support Library (e.g. from here).