In this article we are going to see about vector of vectors in C++ which is equivalent to 2D array in general sense.
Table of Contents
vector of vectors vs 2D array
In the previous article about vector in C++, we have reviewed the comparison of vectors with 1D array. We can extend the similar idea here.
We declare a static 2D array as:
1 2 3 
Type_t array[row_size][column_size] 
Type_t=any data type like int/float/char etc.
array=array name
row_size=number of rows of the array
column_size=number of columns of the array
So, the static 2D array is restricted by its predefined size (in both dimension). But, vector is dynamic in nature. One can extend as much as possible.
Vector of vectors can be supplementary to the 2D array with additional benefits. We can declare such vector of vectors as:
1 2 3 
vector <vector <Type_t> > mtvector; 
Type_t=any data type like int/float/char etc.
myvector =name of the vector of vector
So the outer vector can be thought of as a vector (1D) whose element is also a vector.
Advantages for vector of vectors compared to 2D array, is that one can expand vector as much as he wants. Like, you have no restriction for size. For example,
You need to specify a 2D array as
1 2 3 
int arr[m][n]; //static declaration 
Or if you want to dynamically allocate, still you need size specifications:
1 2 3 4 5 6 
int** arr= (int**)( malloc( sizeof(int*)*m)); for( int i=0;i<m; i++){ arr[i]=(int*)(malloc(sizeof(int)*n)); } 
Where m=row_size
n=col_size
So, there is no way that you can avoid size restrictions. You have to restrict yourself by some predefined sizelimit. Of course, you can set high max limit like following:
1 2 3 4 
#define MAX_LIMIT 1024 int arr[MAX_LIMIT][ MAX_LIMIT]; 
But, it’s wastage of storage simply. Here vector of vectors resolves.
Another important advantage is that in 2D array all the rows must have same dimensions, i.e., every row must have similar number of elements which is column_size.
But for vector, it’s not. Check the following section for example.
Initializing a vector of vectors
You can set a vector of vector to some initial values as per choice like the below way:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 
#include <bits/stdc++.h> using namespace std; int main() { // Initializing 2D vector vector<vector<int> > myvector{ {1,2,3,4}, {4,5,6,7}, {7,8,9,10,11,12} }; // Printing the vector of vectors for (int i = 0; i < myvector.size(); i++) { cout<<"row no: "<<i+1<<endl; cout<<"This row has "<<myvector[i].size()<<" number of elements\n"; cout<<"Elements are:\n"; for (int j = 0; j < myvector[i].size(); j++) cout << vect[i][j] << " "; cout << endl; } return 0; } 
Output:
This row has 4 number of elements
Elements are:
1 2 3 4
row no: 2
This row has 4 number of elements
Elements are:
4 5 6 7
row no: 3
This row has 6 number of elements
Elements are:
7 8 9 10 11 12
Creating a vector of vectors without considering size restriction
To show the above example, consider the following case.
Let’s build a vector of vectors
with type positive integers. Positive numbers will be entered from terminal as elements and 0 to end the row. Follow the code and output to get the details of the example. The main motivation is to show that you don’t need to specify the row_size
or column_size
like you do for 2D array.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 
#include <bits/stdc++.h> using namespace std; int main() { // Declaring vector of vectors vector<vector<int> > myvector; // creating the vector of vectors with input from user cout<<"Instructions\n"; cout<<"1.Start entering positive integers for each row.\n"; cout<<"2.Input 0 if you want to stop extending current row.\n"; cout<<"3.Answer the prompt message appearing for creating new rows\n"; int row_flag; while(true){ cout<<"Do you want to create a new row? Press 1 if yes, else 0\n"; cin>>row_flag; if(row_flag==0) break; cout<<"Ok, you want to create a new row\n"; cout<<"Enter your elements as many as you want. \nLast element should be 0 to indicate the end of row"<<endl; int item; vector<int> inner_vector; cin>>item; while(item){ inner_vector.push_back(item); cin>>item; } //push_back the created 1D vector in the 2D vector //it's exactly same like pushing back other data types //actually it's like datatype for the 2D vector is a 1D vector (vector<int>) myvector.push_back(inner_vector); cout<<"End of current row\n"; } //print the vector cout<<"Printing the vector of vector\n"; for (int i = 0; i < myvector.size(); i++) { cout<<"row no: "<<i+1<<endl; cout<<"This row has "<<myvector[i].size()<<" number of elements\n"; cout<<"Elements are:\n"; for (int j = 0; j < myvector[i].size(); j++) cout << myvector[i][j] << " "; cout << endl; } return 0; } 
1.Start entering positive integers for each row.
2.Input 0 if you want to stop extending current row.
3.Answer the prompt message appearing for creating new rows
Do you want to create a new row? Press 1 if yes, else 0
1
Ok, you want to create a new row
Enter your elements as many as you want.
Last element should be 0 to indicate the end of row
5 3 2 9 0
End of current row
Do you want to create a new row? Press 1 if yes, else 0
1
Ok, you want to create a new row
Enter your elements as many as you want.
Last element should be 0 to indicate the end of row
67 8 0
End of current row
Do you want to create a new row? Press 1 if yes, else 0
1
Ok, you want to create a new row
Enter your elements as many as you want.
Last element should be 0 to indicate the end of row
25 0
End of current row
Do you want to create a new row? Press 1 if yes, else 0
0
Printing the vector of vector
row no: 1
This row has 4 number of elements
Elements are:
5 3 2 9
row no: 2
This row has 2 number of elements
Elements are:
67 8
row no: 3
This row has 1 number of elements
Elements are:
25
Let us elaborate what we did in the above example and the code.

First was to initialize the vector what we have covered already. Second was to create the vector of vectors in C++.
Creating vector of vector is nothing but similar to how we created vector. 
Create a 1D vector first (as discussed in article vector in C++)
Then push it back to the 2D vector as element. The element of 2D vector (vector of vector in our discussion) is a 1D vector. We can create the vector of vectors in that way. The above code has liberty of adding as much column and row as per user need. It’s totally customized, no restriction of size etc. 🙂  Last one is about printing. Same as we printed 1D vector, we just add one more loop to iterate the outer vector.
This is the overall concept of vector of vectors in C++.
Other details about vector of vectors in C++
Here are some other details for vector of vectors.
Resize()
If you want to bring 2D array kind of behaviour to vector of declaring a predefined size, resize() function helps.
Following is the example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 
#include <bits/stdc++.h> using namespace std; #define row_size 10 #define column_size 10 int main() { // Declaring vector of vectors vector<vector<int> > myvector(row_size); for(int i=0;i<row_size;i++){ //defining size for each vector elements of the 2D vector myvector[i].resize(column_size); } } 
Fill Constructor
Another way of doing the same thing is by using fill constructor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 
#include <bits/stdc++.h> using namespace std; #define row_size 10 #define column_size 10 int main() { // Declaring vector of vectors vector<vector<int> > myvector(row_size,vector<int>( column_size)); } 
That’s all about vector of vectors in C++.