This post will discuss how to print a vector in C++.
Vectors are the dynamic, re-sizable implementation of array data structure in C++. The vector elements are stored in contiguous locations, which makes the element access easier, and hence we can print a vector in several ways as covered below:
1. Using Indices
A naive solution is to iterate through elements of the vector using a simple for-loop and access its elements using the []
operator or at()
function using the corresponding index.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <iostream> #include <vector> void print(std::vector<int> const &input) { for (int i = 0; i < input.size(); i++) { std::cout << input.at(i) << ' '; } } int main() { std::vector<int> input = { 1, 2, 3, 4, 5 }; print(input); return 0; } |
Output:
1 2 3 4 5
Please note that std::vector has a member type size_type
which is returned by std::vector::size
function. It is usually the same as size_t
.
1 2 3 |
for (std::vector<int>::size_type i = 0; i < input.size(); i++) { std::cout << input.at(i) << ' '; } |
2. Using std::copy
function
We can also use std::copy
to copy the vector’s contents to the output stream std::cout
with the help of the output iterator std::ostream_iterator
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <iostream> #include <vector> #include <algorithm> #include <iterator> void print(std::vector<int> const &input) { std::copy(input.begin(), input.end(), std::ostream_iterator<int>(std::cout, " ")); } int main() { std::vector<int> input = { 1, 2, 3, 4, 5 }; print(input); return 0; } |
Output:
1 2 3 4 5
With C++17, we can use std::copy
with std::experimental::ostream_joiner which is defined in header <experimental/iterator>
. It is a single-pass output iterator which can write successive objects into the std::cout
, using the <<
operator, separated by a delimiter between every two objects.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include <iostream> #include <vector> #include <experimental/iterator> void print(std::vector<int> const &input) { std::copy(input.begin(), input.end(), std::experimental::make_ostream_joiner(std::cout, " ")); } int main() { std::vector<int> input = { 1, 2, 3, 4, 5 }; print(input); return 0; } |
Output:
1 2 3 4 5
3. Using range-based for-loop
With C++11, the recommended approach is to use the range-based for-loop to print elements of a container:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <iostream> #include <vector> void print(std::vector<int> const &input) { for (auto const &i: input) { std::cout << i << " "; } } int main() { std::vector<int> input = { 1, 2, 3, 4, 5 }; print(input); return 0; } |
Output:
1 2 3 4 5
4. Using std::for_each
function
Another elegant solution is to use std::for_each
, which takes a range defined by two input iterators and applies a function on every element in that range. The function can be a unary function, or an object of a class overloading the ()
operator or a lambda expression.
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 |
#include <iostream> #include <vector> #include <algorithm> void print(const int &i) { std::cout << i << ' '; } struct myclass { void operator() (int i) { std::cout << i << ' '; } } ob; void print_vector(std::vector<int> const &input) { // specify a lambda expression std::for_each(input.begin(), input.end(), [](const auto &e) { std::cout << e << " "; }); // or pass an object of a class overloading the `()operator` // std::for_each(input.begin(), input.end(), ob); // or specify a function // std::for_each(input.begin(), input.end(), print); } int main() { std::vector<int> input = { 1, 2, 3, 4, 5 }; print_vector(input); return 0; } |
Output:
1 2 3 4 5
5. Using Iterator
We can also use the iterators to print a vector. The idea is to use the constant iterators, returned by cbegin()
and cend()
, since we’re not modifying the vector’s contents inside the loop. Before C++11, we can use begin()
and end()
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <iostream> #include <vector> void print(std::vector<int> const &input) { for (auto it = input.cbegin(); it != input.cend(); it++) { std::cout << *it << ' '; } } int main() { std::vector<int> input = { 1, 2, 3, 4, 5 }; print(input); return 0; } |
Output:
1 2 3 4 5
6. Overloading <<
Operator
We know that the output streams use the insertion (<<)
operator for standard types. To get std::cout
to accept a vector object after the <<
operator, we need to overload the <<
operator to recognize an ostream object on the left and a vector object on the right, as shown below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include <iostream> #include <vector> std::ostream &operator<<(std::ostream &os, const std::vector<int> &input) { for (auto const &i: input) { os << i << " "; } return os; } int main() { std::vector<int> input = { 1, 2, 3, 4, 5 }; std::cout << input; return 0; } |
Output:
1 2 3 4 5
That's all about printing a vector in C++.