Say I have a vector with values [1,2,3,4,5,6,7,8,9,10]. I want to create a new vector that refers to, for example, [5,6,7,8]. I imagine this is just a matter of creating a vector with pointers or do I have to push_back all the intermediary values I need?
Asked
Active
Viewed 4.9k times
28
-
The given answers so far are all good options. While you *could* create a vector of pointers to your subrange, you probably don't want to. If the original vector ever grows to the point where it has to re-allocate its internal storage, your pointers would all become invalid. Especially when dealing with such small ranges, working with a copy is preferable. – Michael Kristofik Mar 14 '12 at 16:18
-
Define "refers to". What should happen if the original vector changes? – Karl Knechtel Mar 14 '12 at 16:43
-
3Possible duplicate of [Best way to extract a subvector from a vector?](http://stackoverflow.com/questions/421573/best-way-to-extract-a-subvector-from-a-vector) – TobiMcNamobi Apr 12 '17 at 08:38
4 Answers
52
One of std::vector
's constructor accepts a range:
std::vector<int> v;
// Populate v.
for (int i = 1; i <= 10; i++) v.push_back(i);
// Construct v1 from subrange in v.
std::vector<int> v1(v.begin() + 4, v.end() - 2);

hmjd
- 120,187
- 20
- 207
- 252
4
You don't have to use push_back
if you don't want to, you can use std::copy
:
std::vector<int> subvector;
copy ( v1.begin() + 4, v1.begin() + 8, std::back_inserter(subvector) );

Michael Kristofik
- 34,290
- 15
- 75
- 125

Luchian Grigore
- 253,575
- 64
- 457
- 625
-
2Shouldn't you initialize subvector to the correct size before copying into it? – obmarg Mar 14 '12 at 16:07
-
2
-
@obmarg yes or use a back insertion iterator - `std::back_inserter` will make one for you – Flexo Mar 14 '12 at 16:09
-
@Kristo (and @awoodland) Yes. Though from my experience they tend to be slow, do they not just use push_back behind the scenes? – obmarg Mar 14 '12 at 16:11
-
Inserting one element at a time (as `insert_iterator`s do) will usually be slower than inserting a range all at once. But for vectors of such small size as this example, I doubt it matters. – Michael Kristofik Mar 14 '12 at 16:15
-
you can always use `reserve()` with an insertion iterator to avoid reallocation too. – Flexo Mar 14 '12 at 16:20
-
2Since it's been 30 minutes and @Luchian hasn't noticed our comments yet, I went ahead and edited the code. – Michael Kristofik Mar 14 '12 at 16:33
4
This is fairly easy to do with std::valarray
instead of a vector:
#include <valarray>
#include <iostream>
#include <iterator>
#include <algorithm>
int main() {
const std::valarray<int> arr={0,1,2,3,4,5,6,7,8,9,10};
const std::valarray<int>& slice = arr[std::slice(5, // start pos
4, // size
1 // stride
)];
}
Which takes a "slice" of the valarray, more generically than a vector.
For a vector you can do it with the constructor that takes two iterators though:
const std::vector<int> arr={0,1,2,3,4,5,6,7,8,9,10};
std::vector<int> slice(arr.begin()+5, arr.begin()+9);

Flexo
- 87,323
- 22
- 191
- 272
3
I would do the following:
#include <vector>
#include <iostream>
using namespace std;
void printvec(vector<int>& v){
for(int i = 0;i < v.size();i++){
cout << v[i] << " ";
}
cout << endl;
}
int main(){
vector<int> v;
for(int i = 1;i <= 10;i++) v.push_back(i);
printvec(v);
vector<int> v2(v.begin()+4, v.end()-2);
printvec(v2);
return 0;
}
~

Taylor Southwick
- 1,456
- 13
- 14