std::vector is a container class type for an array in C++. It is defined in header file <vector> as class template with a template type parameter to defined what type of values it can store.
An array using std::vector can simply be created by providing a list of values as shown below:
#include <iostream>
#include <vector>
int main(int argc, char const *argv[])
{
std::vector empty{}; // creating empty (with zero elements) array
std::vector items{1, 2, 3, 4, 5};
return 0;
}First shows creating an empty array with zero elements, Second shows the creation of array with 5 elements.
How does this initialization works?
std::vector has a special constructor called list constructor (explained in std::initializer_list) that gets invoked when it is initialized using a list initialization. The constructor does the following tasks when invoked:
- Ensures the container has enough storage for all the values.
- Sets the container length with the total values provided in the list.
- Initializes the elements to the values provided in the list in sequential order.
Accessing array elements using operator[]
We can access array individual elements using operator[] called subscript operator. It is the square braces where we provide the an integral value which is called a subscript or index and it gives the reference to the actual element (not copy). The indexing starts with 0 and goes till of the array where is the total elements in the array.
For example,
items[0]; // gives reference to first element
items[1]; // gives reference to second element
// ...
items[4]; // gives reference to the last elementIt is to be noted that we should provide a valid index which should be <=length - 1. Because operator[] does not do bound checking, failing to do so results in undefined behavior and maybe the program would crash.
Tip
std::vectoralso provides a member function.at()which can be used to access elements. This function checks the bounds and throwsstd::out_of_rangeexception..at()is slower thanoperator[]because it does bounds check every time the call is made.
Creating an array of a specified length
If we want to create an array of a specific length to be filled up later, std::vector provides an explicit constructor explicit std::vector<T>(std::size_t) which accepts a single std::size_t value specifying total elements. This constructor is called using direct initialization.
For example,
#include <iostream>
#include <vector>
int main(int argc, char const *argv[])
{
std::vector<int> items(10); // direct initialization uses explicit constructor with single argument.
std::cout << items[0] << "\n";
return 0;
}This creates an array of 10 elements value-initialized to zero. If element type is program defined (class type), the default constructor gets called.
List initializer and list constructors
For a non-empty list initializer, a matching list constructor will always take preference over other constructors. For example,
std::vector<int> items{10};Would invoke list constructor that creates an array of 1 element with value 10. If this rule was not there, there would be multiple matches for single argument initializer and compiler would throw compilation error for multiple matches.
Const and constexpr with std::vector
We can create a const std::vector array. Once initialized with a set of values, the array elements can’t be modified. Elements are treated as if they are const.
For example:
const std::vector items{1, 2, 3, 4};
items[0] = 3; // would fail.std::vector can’t be made constexpr. std::array can be made constexpr if we want to use.