Print a std::set or std::unordered_set in C++
This post will discuss how to print a std::set or std::unordered_set in C++.
1. Using std::copy function
The idea is to copy the set’s contents to the output stream (which happens to be std::cout here) by using std::copy, which takes an 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 <unordered_set> #include <algorithm> #include <iterator> void print(std::unordered_set<int> const &s) { std::copy(s.begin(), s.end(), std::ostream_iterator<int>(std::cout, " ")); } int main() { std::unordered_set<int> s = { 5, 3, 2, 4, 1 }; print(s); return 0; } |
Output:
1 5 3 2 4
From C++17 onwards, we can use std::experimental::ostream_joiner defined in <experimental/iterator> header.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include <iostream> #include <unordered_set> #include <experimental/iterator> void print(std::unordered_set<int> const &s) { std::copy(s.begin(), s.end(), std::experimental::make_ostream_joiner(std::cout, " ")); } int main() { std::unordered_set<int> s = { 5, 3, 2, 4, 1 }; print(s); return 0; } |
Output:
1 4 2 3 5
2. Using range-based for-loop
The recommended approach in C++11 is to use the new range-based for-loops for printing the set elements.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <iostream> #include <unordered_set> void print(std::unordered_set<int> const &s) { for (auto const &i: s) { std::cout << i << " "; } } int main() { std::unordered_set<int> s = { 5, 3, 2, 4, 1 }; print(s); return 0; } |
Output:
1 5 3 2 4
3. 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 <unordered_set> #include <algorithm> struct myclass { void operator() (int i) { std::cout << i << ' '; } } ob; void print(const int &i) { std::cout << i << ' '; } void print_set(std::unordered_set<int> const &s) { // specify a lambda expression std::for_each(s.begin(), s.end(), [](const int &e) { std::cout << e << " "; }); // or pass an object of a class overloading the ()operator // std::for_each(s.begin(), s.end(), ob); // or specify a function // std::for_each(s.begin(), s.end(), print); } int main() { std::unordered_set<int> s = { 5, 3, 2, 4, 1 }; print_set(s); return 0; } |
Output:
1 5 3 2 4
4. Using Iterator
We can also use iterators to iterate a set and print its contents. Also, from C++11 onwards, it is recommended to use the constant iterators to not modify the set’s contents inside the loop.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <iostream> #include <unordered_set> void print(std::unordered_set<int> const &s) { for (auto it = s.cbegin(); it != s.cend(); it++) { std::cout << *it << ' '; } } int main() { std::unordered_set<int> s = { 5, 3, 2, 4, 1 }; print(s); return 0; } |
Output:
1 5 3 2 4
5. Overloading << Operator
To get std::cout to accept any set object after the insertion (<<) operator, we can overload the << operator to recognize an ostream object on the left and a set 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 <unordered_set> std::ostream &operator<<(std::ostream &os, const std::unordered_set<int> &s) { for (auto const &i: s) { os << i << " "; } return os; } int main() { std::unordered_set<int> s = { 5, 3, 2, 4, 1 }; std::cout << s; return 0; } |
Output:
1 5 3 2 4
That's all about printing a std::set or std::unordered_set in C++.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)