28

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?

hmjd
  • 120,187
  • 20
  • 207
  • 252
John Smith
  • 11,678
  • 17
  • 46
  • 51
  • 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
  • 3
    Possible 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 Answers4

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
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