What's the C++ way to print or cout
a C++ standard library container to the console, to view its contents?
On a separate note, why doesn't the C++ library actually overload the <<
operator for you? Any history behind it?
What's the C++ way to print or cout
a C++ standard library container to the console, to view its contents?
On a separate note, why doesn't the C++ library actually overload the <<
operator for you? Any history behind it?
Overloading the operator<<
for ostream
is the way to go. Here's one possibility:
template <class container>
std::ostream& operator<<(std::ostream& os, const container& c)
{
std::copy(c.begin(),
c.end(),
std::ostream_iterator<typename container::value_type>(os, " "));
return os;
}
Then you can simply write:
std::cout << SomeContainer << std::endl;
Here are some other actually really nice solutions: Pretty-print C++ STL containers
The simplest way is to use the range-based for statement. For example
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
template <class Container>
std::ostream & display( const Container &container,
const char *s = " ",
std::ostream &os = std::cout )
{
for ( const auto &value : container )
{
os << value << s;
}
return os;
}
int main()
{
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int> v( std::begin( a ), std::end( a ) );
display( a, "; " );
std::cout << std::endl;
display( v );
std::cout << std::endl;
return 0;
}
The program output is
0; 1; 2; 3; 4; 5; 6; 7; 8; 9;
0 1 2 3 4 5 6 7 8 9
However a more flexibale approach will be to use standard algorithm std::copy
. In this case you can set the displayed range yourself and use reverse iterators.
Also you can write the function such a way that it would get additional information.
why doesn't the C++ library actually overload the << operator for you?
Because any user can use his own approach to output a container as you can see from the output of my demonstrative program. In fact a container is a user-defined class and it is the user who should overload operator <<. There is exceptions for std::string and std::bitset but strings and bitsets are outputed as one entity without intermediate separates similarly to fundamental types.
For variety, make an adaptor, something like
template< typename T >
struct SequencePrinter
{
const T& t;
// ...
};
template< typename T >
SequencePrinter<T> sequence_printer(const T&);
template< typename T >
ostream& operator<<(ostream&, SequencePrinter<T>);
int main() {
vector<int> v;
// ...
cout << sequence_printer(v) << endl;
}
This allows the usual <<
notation, but doesn't try to force a particular choice of what <<
should mean with a sequence. It could, of course, be made fairly configurable too.