Also referred to as vector of vectors, 2D vectors in C++ form the basis of creating matrices, tables, or any other structures, dynamically. Before arriving on the topic of 2D vectors in C++, it is advised to go through the tutorial of using single-dimensional vectors in C++.

It would be impossible for us to use vectors in C++, if not for the header files that are included at the beginning of the program. To make use of 2D vectors, we include:

```
#include<vector>
```

Instead of including numerous kinds of Standard Template Libraries (STL) one by one, we can include all of them by:

```
#include<bits/stdc++.h>
```

Firstly, we will learn certain ways of initializing a 2-D vector. The following code snippet explains the initialization of a 2-D vector when all the elements are already known.

```
#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<vector<int>> v {{1, 0, 1}, {0, 1}, {1, 0, 1}};
for(int i=0;i<v.size();i++){
for(int j=0;j<v[i].size();j++)
cout<<v[i][j]<<" ";
cout<<endl;
}
}
```

After running the above code, we get the following output:

```
1 0 1
0 1
1 0 1
```

The use of `'vector<vector<>>'`

symbolizes that we are working on a vector of vectors. Each value inside the first set of braces, like `'{1, 0, 1}'`

and `'{0, 1}'`

are vectors independently.

Note: To create 2D vectors in C++ of different data-type, we can place the data-type inside the innermost angle brackets like`<char>`

.

Since we are working on a two-dimensional data structure, we require two loops for traversing the complete data structure, efficiently. The outer loop moves along the rows, whereas the inner loop traverses the columns.

Note:The`'size()'`

function provides the number of vectors inside the 2D vector, not the total number of elements inside each individual vectors.

2D vectors can be of large sizes. We can not expect the programmer to feed-in every single value. Therefore, we can initialize a 2-D vector on the basis of the number of rows and columns.

```
#include<iostream>
#include<vector>
using namespace std;
int main(){
//Number of columns
int num_col = 3;
// Number of rows
int num_row = 4;
// Initializing a single row
vector<int> row(num_col, 0);
// Initializing the 2-D vector
vector<vector<int>> v(num_row, row) ;
for(int i=0;i<v.size();i++){
for(int j=0;j<v[i].size();j++)
cout<<v[i][j]<<" ";
cout<<endl;
}
}
```

The output would be:

```
0 0 0
0 0 0
0 0 0
0 0 0
```

According to the standard initialization of a vector,`'vector<int> v(10, 0)'`

, the first argument denotes the size of the vector whereas the second denotes the default value every cell holds.

In the above code snippet, we follow two steps of standard initialization:

`'vector<int> row(num_col, 0)'`

- In this statement, we create a single-dimensional vector called`'row'`

, which has length defined by`'num_col'`

and default values as`'0'`

. It basically forms each row of our two-dimensional vector.`'vector<vector<int>> v(num_row, row)`

- In this statement, we create our complete two-dimensional vector, by defining every value of the 2-D vector as the`'row'`

created in the last statement.

After understanding the above procedure, we can improve our initialization of 2D vectors in C++ by:

```
#include<iostream>
#include<vector>
using namespace std;
int main(){
//Number of columns
int num_col = 3;
// Number of rows
int num_row = 4;
// Initializing the 2-D vector
vector<vector<int>> v(num_row, vector<int> (num_col, 0)) ;
for(int i=0;i<v.size();i++){
for(int j=0;j<v[i].size();j++)
cout<<v[i][j]<<" ";
cout<<endl;
}
}
```

The above code, will provide the similar output as before, since we are doing the exact same thing, but in a single line of code.

If we remember correctly, the standard initialization looks somewhat like the above one. Creating a two-dimensional vector requires us to set the default value for every element as a single-dimensional vector.

The last method involves creating a 2-D vector without the knowledge of rows or columns. It is done by:

```
vector<vector<int>> v;
```

The above declaration creates an empty container capable of storing elements in the form of vectors.

Instead of traversing a 2D vector using indices, C++ has a provision of iterators for every specific STL data structure.

```
#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<vector<int>> v {{1, 0, 1}, {0, 1}, {1, 0, 1}};
// Iterator for the 2-D vector
vector<vector<int>>::iterator it1;
// Iterator for each vector inside the 2-D vector
vector<int>::iterator it2;
// Traversing a 2-D vector using iterators
for(it1 = v.begin();it1 != v.end();it1++){
for(it2 = it1->begin();it2 != it1->end();it2++)
cout<<*it2<<" ";
cout<<endl;
}
}
```

**Output:**

```
1 0 1
0 1
1 0 1
```

The iterators come in handy when we use certain operations that require an argument for positioning. The two most used functions returning iterator values are:

`'v.begin()'`

- It returns an iterator to the first vector in a 2-D vector.`'v.end()'`

- It returns an iterator to the end of the 2-D vector.

Let us look at some operations possible on a 2-D vector.

To add elements at the end of a two-dimensional vector, we use `'push_back()'`

function.

```
#include<iostream>
#include<vector>
using namespace std;
int main(){
// Initializing the 2-D vector
vector<vector<int>> v;
v.push_back({1, 0, 1});
v.push_back({0, 1});
v.push_back({1, 0, 1});
for(int i=0;i<v.size();i++){
for(int j=0;j<v[i].size();j++)
cout<<v[i][j]<<" ";
cout<<endl;
}
}
```

**Output:**

```
1 0 1
0 1
1 0 1
```

Since our container is a vector of vectors, it would only make sense to push complete vectors inside it. Therefore, the argument passed inside the `'push_back()'`

function must be a vector.

Note:`'v[i]'`

represents a single-dimensional vector. Therefore, if the programmer needs to add elements in a certain vector inside the 2-D vector, he may use`'v[i].push_back(value)'`

.

To add a complete vector at a specific location, we use the `'insert()'`

function.

```
#include<iostream>
#include<vector>
using namespace std;
int main(){
// Initializing the 2-D vector
vector<vector<int>> v;
v.push_back({1, 0, 1});
v.push_back({0, 1});
v.push_back({1, 0, 1});
// Iterator for the 2-D vector
vector<vector<int>>::iterator it = v.begin();
// Inserting the vector = {1, 2, 3} as the second vector
v.insert(it + 1, {1, 2, 3});
for(int i=0;i<v.size();i++){
for(int j=0;j<v[i].size();j++)
cout<<v[i][j]<<" ";
cout<<endl;
}
}
```

**Output:**

```
1 0 1
1 2 3
0 1
1 0 1
```

The `'insert()'`

function requires a positional argument as an iterator not as an integral index. It is followed by a vector that is supposed to be inserted at the specified location.

Opposite to the `'push_back()'`

, C++ provides `'pop_back()'`

function with the duty of removing the last element from the given vector.

In the context of this article, `'pop_back()'`

function would be responsible for removing the last vector from a 2-D vector.

```
#include<iostream>
#include<vector>
using namespace std;
int main(){
// Initializing the 2-D vector
vector<vector<int>> v ;
// Adding vectors to the empty 2-D vector
v.push_back({1, 0, 1});
v.push_back({0, 1});
v.push_back({1, 0, 1});
// Remove the last vector from a 2-D vector
v.pop_back();
for(int i=0;i<v.size();i++){
for(int j=0;j<v[i].size();j++)
cout<<v[i][j]<<" ";
cout<<endl;
}
}
```

**Output:**

```
1 0 1
0 1
```

In addition to the `'pop_back()'`

function, we have an `'erase()'`

function using which we can remove elements from a specified index.

```
#include<iostream>
#include<vector>
using namespace std;
int main(){
// Initializing the 2-D vector
vector<vector<int>> v ;
// Pushing vector inside the empty 2-D vector
v.push_back({1, 0, 1});
v.push_back({0, 1});
v.push_back({1, 0, 1});
// Iterator for the 2-D vector
vector<vector<int>>::iterator it = v.begin();
// Remove the second vector from a 2-D vector
v.erase(it + 1);
for(int i=0;i<v.size();i++){
for(int j=0;j<v[i].size();j++)
cout<<v[i][j]<<" ";
cout<<endl;
}
}
```

**Output:**

```
1 0 1
1 0 1
```

Similar to the `'insert()'`

function, it requires a positional argument as an iterator. To remove all the vectors from the 2-D vector, `'clear()'`

function can be used.

The above functions might be enough to get comfortable while using 2-D vectors in C++.

Two-dimensional vectors in C++ are very easy to use, provided that the programmer is aware of the syntax involved. This kind of vector comes in handy when we solve problems related to matrices, graphs, and other two-dimensional objects.

We hope that this tutorial enlightened the reader on the topic of using 2-D vectors. Feel free to comment below for any queries related to the topic.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Sign up for Infrastructure as a Newsletter.

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.