overloading << operator for c++ stl containers - c++

I wish I could just print contents of a set/vector/map by using cout << . It doesn't seem so difficult for the stl designers to implement : Assuming that << is defined for T, << for a container could just iterate through the elements and print them using ofstream << .
Is there an easy way to print them that I dont know of?
If not, Is there an easy solution? I have read at places that extending stl classes is a bad idea. Is that so, and why?
how about defining an something like an overloaded print function?
EDIT:
I am looking for a recursive function which can handle containers of containers of ...
I agree that different people would like different formats, but something overridable is better than nothing

Probably the easiest way to output an STL container is
std::copy(cont.begin(), cont.end(),
std::ostream_iterator<Type>(std::cout, " "));
where Type is the type of the elements of cont (e.g. if cont is of type std::vector<int> then Type must be int).
Of course instead of std::cout you can use any ostream.

In C++11 you can use range-based for:
for (auto& i: container) cout << i << " ";
cout << endl;

The easiest eay to dump a container is probably just using std::copy(). For example I typically use something like this:
template <typename C>
std::string format(C const& c) {
std::ostringstream out;
out << "[";
if (!c.empty()) {
std::copy(c.begin(), --c.end(),
std::ostream_iterator<typename C::value_type>(out, ", "));
out << c.back();
}
out << "]";
return out.str();
}
Yes, this doesn't always work but works for my needs. This actually shows one of the problems why there is no output for containers in the standard library: there are many different ways how containers can be formatted. To make matters worse, the formatted output should be readable where thing become real fun. All of this is doable but I'm not aware of a corresponding proposal.

It doesn't seem so difficult for the stl designers to implement : Assuming that << is defined for T, << for a container could just iterate through the elements and print them using ofstream << .
Of course it is not hard for them. However, ask yourself: Does the format of the output make sense for every client? The standard library is about reuse and genericity. Coupling containers with some arbitrary output formatting rules makes them less generic for the sake of only some.
The recommended solution therefore is to provide your own operator<<(std::ostream &, T) and/or to take other generic algorithms, as found in e.g. <algorithms>.

Are you looking something like this?
#include <iostream>
#include <set>
template <typename T>
std::ostream& operator<< (std::ostream& os, const std::set<T>& s)
{
for( auto i: s ) {
os << i << " ";
}
return os;
}
Then you just may use it this way:
std::set<int> my_set = { 11, 12, 13 };
std::cout << my_set << std::endl;

Using Template template parameter makes it easy, in order to make it working for each collection you need both template<class, class...> class X and class... Args as template parameters:
template<class T, template<class, class...> class X, class... Args>
std::ostream& operator <<(std::ostream& os, const X<T, Args...>& objs) {
os << "{";
bool commoFlag = false;
for (auto const& obj : objs) {
os << (commoFlag ? ", " : "") << obj;
commoFlag = true;
}
os << "}";
return os;
}
vector<float> f_vec{ 1.3f , 5.134f, 5.78f };
list<char> c_lst{ 'F','O', 'M', 'S', 'A' };
set<int> i_st{ 17,14, -70 };
std::cout << f_vec << std::endl;
std::cout << c_lst << std::endl;
std::cout << i_st << std::endl;
output:
{1.3, 5.134, 5.78}
{F, O, M, S, A}
{-70, 14, 17}

Related

Correct use of template with a class member function

the concept of templates is quite difficult to grasp quickly. I need a class member function to iterate over vector of any objects and print them all out. Can I do this with using templates? I.e.:
void SomeClass::printAll(std::vector< any type here> array) {
for (auto & o : array) {
std::cout << o << std::end;
}
}
If this is possible in C++, how would I define it in the header and implementation files, I dare guess the syntax might be different.
Many thanks in advance for helping with this naive questions.
Trying to grasp any non-trivial topic quickly is difficult. Just don't do it, but go slowly. That also means not trying to understand more than one thing at a time. I don't know why that function has to be member of a class. Make it a free function:
template <typename T>
void printAll(const std::vector<T>& vect) {
for (const auto& o : vect) {
std::cout << o << "\n";
}
}
Don't pass by value when you can pass by const reference. I would prefer \n here rather than std::endl (not std::end) because std::endl flushes the stream. Choose names carefully, a std::vector is not an array.
The above will only work with vectors, but it can be more flexible for example by passing iterators:
template <typename IT>
void printAll(IT begin, IT end) {
for ( ; begin != end; ++begin) {
std::cout << *begin << "\n";
}
}

Outputting a Returned pair Without a Temporary

Let's say that I have a function: pair<int, int> foo() I want to directly output both elements of this without using a temporary.
Is there a way that I can output this, or maybe convert it into a string to output? Could I perhaps use tie to do this?
Here's what I'm trying to do with the temporary:
const auto temporary = foo();
cout << temporary.first << ' ' << temporary.second << endl;
In c++17 standard, you can use structured binding declaration
std::pair<int, int> get_pair()
{
return {10, 20};
}
int main()
{
auto [x, y] = get_pair();
std::cout << x << " " << y << std::endl;
return 0;
}
No. You can't write that function without using a non-temporary. If you really need to, you should probably change the structure of your code. Technically, you could also use a global variable (although I strongly do not recommend this). I don't think tie would work for what you want it for either.
You can create a small class that wraps the std::pair, and enable output streams to print it via operator<<:
template<typename PairT>
struct printable {
const PairT& p;
printable(const PairT& p)
: p{p}
{}
};
template<typename CharT, typename PairT>
std::basic_ostream<CharT>& operator<<(std::basic_ostream<CharT>& out, const printable<PairT>& pair) {
out << pair.p.first << ' ' << pair.p.second;
return out;
}
Then you can use it like this:
auto foo() {
return std::pair<int, int>(1, 2);
}
int main() {
std::cout << printable(foo());
}
Live example
Of course, you could also just enable the printing directly for an std::pair...
template<typename CharT, typename A, typename B>
std::basic_ostream<CharT>& operator<<(std::basic_ostream<CharT>& out, const std::pair<A, B>& pair) {
out << pair.first << ' ' << pair.second;
return out;
}
// (...)
std::cout << foo(); // And this would work just fine
... but I don't really recommend it, specially on a header, since you would be basically changing behavior of standard types and your colleagues (or yourself, in the future) may be confused by it.

How to implement template function like add(T a, K b) with std::any elegant and without template? [duplicate]

I have a "dictionary" std::map<std::string, boost::any> (or std::any, if you want) that can possibly be nested. Now, I would like to display the map. Since boost::any obviously doesn't play nicely with <<, things are getting a little nasty. So far, I'm checking the type, cast it, and pipe the cast to cout:
for (const auto &p: map) {
std::cout << std::string(indent + 2, ' ') << p.first << ": ";
if (p.second.type() == typeid(int)) {
std::cout << boost::any_cast<int>(p.second);
} else if (p.second.type() == typeid(double)) {
std::cout << boost::any_cast<double>(p.second);
} else if (p.second.type() == typeid(std::string)) {
std::cout << boost::any_cast<std::string>(p.second);
} else if (p.second.type() == typeid(const char*)) {
std::cout << boost::any_cast<const char*>(p.second);
} else if (p.second.type() == typeid(std::map<std::string, boost::any>)) {
show_map(
boost::any_cast<std::map<std::string, boost::any>>(p.second),
indent + 2
);
} else {
std::cout << "[unhandled type]";
}
std::cout << std::endl;
}
std::cout << std::string(indent, ' ') << "}";
This prints, for example
{
fruit: banana
taste: {
sweet: 1.0
bitter: 0.1
}
}
Unfortunately, this is hardly scalable. I'd have to add another else if clause for every type (e.g., float, size_t,...), which is why I'm not particularly happy with the solution.
Is there a way to generalize the above to more types?
One thing you can do to lessen (but not remove) the pain is to factor the type determination logic into one support function, while using static polymorphism (specifically templates) for the action to be applied to the values...
#include <iostream>
#include <boost/any.hpp>
#include <string>
struct Printer
{
std::ostream& os_;
template <typename T>
void operator()(const T& t)
{
os_ << t;
}
};
template <typename F>
void f_any(F& f, const boost::any& a)
{
if (auto p = boost::any_cast<std::string>(&a)) f(*p);
if (auto p = boost::any_cast<double>(&a)) f(*p);
if (auto p = boost::any_cast<int>(&a)) f(*p);
// whatever handling for unknown types...
}
int main()
{
boost::any anys[] = { std::string("hi"), 3.14159, 27 };
Printer printer{std::cout};
for (const auto& a : anys)
{
f_any(printer, a);
std::cout << '\n';
}
}
(With only a smidge more effort, you could have the type-specific test and dispatch done for each type in a variadic template parameter pack, simplifying that code and the hassle of maintaining the list. Or, you could just use a preprocessor macro to churn out the if-cast/dispatch statements....)
Still - if you know the set of types, a boost::variant is more appropriate and already supports similar operations (see here).
Yet another option is to "memorise" how to do specific operations - such as printing - when you create your types:
#include <iostream>
#include <boost/any.hpp>
#include <string>
#include <functional>
struct Super_Any : boost::any
{
template <typename T>
Super_Any(const T& t)
: boost::any(t),
printer_([](std::ostream& os, const boost::any& a) { os << boost::any_cast<const T&>(a); })
{ }
std::function<void(std::ostream&, const boost::any&)> printer_;
};
int main()
{
Super_Any anys[] = { std::string("hi"), 3.14159, 27 };
for (const auto& a : anys)
{
a.printer_(std::cout, a);
std::cout << '\n';
}
}
If you have many operations and want to reduce memory usage, you can have the templated constructor create and store a (abstract-base-class) pointer to a static-type-specific class deriving from an abstract interface with the operations you want to support: that way you're only adding one pointer per Super_Any object.
Since you're already using Boost you could consider boost::spirit::hold_any.
It already has pre-defined streaming operators (both operator<<() and operator>>()).
Just the embedded type must have the corresponding operator defined, but in your use context this seems to be completely safe.
Despite being in the detail namespace, hold_any is quite widespread and almost a ready-to-use boost:any substitute (e.g. Type Erasure - Part IV, Why you shouldn’t use boost::any)
A recent version of Boost is required (old versions had a broken copy assignment operator).

C++: Printing or cout a standard library container to console

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.

How to print boost::any to a stream?

I have a Map std::map<std::string, boost::any>, which comes from the boost::program_options package. Now I would like to print the content of that map:
for(po::variables_map::const_iterator it = vm.begin(); it != vm.end(); ++it) {
std::cerr << it->first << ": " << it->second << std::endl;
}
Unfortunately, that is not possible because boost::any doesn't have an operator<< defined.
What is the easiest way to print that map?
I could define my own output operator for any that automatically tries to cast each any to an int, then double, then string, etc., each time ignoring errors and trying to cast until the cast is successful and I can print as the specified type.
But there should be an easier method in Boost? I'd need something like a reverse lexical_cast...
You could use boost::spirit::hold_any instead. It's defined here:
#include <boost/spirit/home/support/detail/hold_any.hpp>
and is fully compatible with boost::any. This class has two differences if compared to boost::any:
it utilizes the small object optimization idiom and a couple of other optimization tricks, making spirit::hold_any smaller and faster than boost::any
it has the streaming operators (operator<<() and operator>>()) defined, allowing to input and output a spirit::hold_any seemlessly.
The only limitation is that you can't input into an empty spirit::hold_any, but it needs to be holding a (possibly default constructed) instance of the type which is expected from the input.
If you can change boost::any to another type, you can use Boost.TypeErasure. If you ever wanted to create a type that's like any, but only supporting types that support these particular operations at compile time, then this is just for you.
#include <boost/type_erasure/operators.hpp>
#include <boost/type_erasure/any.hpp>
#include <boost/mpl/vector.hpp>
#include <random>
#include <iostream>
namespace te = boost::type_erasure;
typedef te::any<boost::mpl::vector<
te::copy_constructible<>,
te::destructible<>,
te::ostreamable<>
>> streamable_any;
int main()
{
streamable_any i(42);
streamable_any d(23.5);
std::mt19937 mt;
streamable_any r(mt);
std::cout << i << "\n" << d << "\n" << r << "\n";
}
Live On Coliru
Unfortunately, with any the only way is to use the type() method to determine what is contained within any, then cast it with any_cast. Obviously you must have RTTI enabled, but you probably already do if you're using any:
for(po::variables_map::const_iterator it = vm.begin(); it != vm.end(); ++it) {
if(typeid(float) == it->second.type()) {
std::cerr << it->first << ": " << any_cast<float>(it->second) << std::endl;
}
else if(typeid(int) == it->second.type()) {
std::cerr << it->first << ": " << any_cast<int>(it->second) << std::endl;
}
...
}
Define some aux function to output to stream:
template<class T>
bool out_to_stream(std::ostream& os, const boost::any& any_value)
{
try {
T v = boost::any_cast<T>(any_value);
os << v;
return true;
} catch(boost:: bad_any_cast& e) {
return false;
}
}
You can define a special formatting for some types
template<>
bool out_to_stream<std::string>(std::ostream& os, const boost::any& any_value)
{
try {
std::string v(std::move(boost::any_cast<std::string>(any_value)));
os << "'" << v << "'";
return true;
} catch(boost:: bad_any_cast& e) {
return false;
}
}
or
template<>
bool out_to_stream<bool>(std::ostream& os, const boost::any& any_value)
{
try {
os << ((boost::any_cast<bool>(any_value))? "yes" : "no");
return true;
} catch(boost:: bad_any_cast& e) {
return false;
}
}
Then define an output operator for boost::any where you list all types you want to try to cast and output
std::ostream& operator<<(std::ostream& os, const boost::any& any_value)
{
//list all types you want to try
if(!out_to_stream<int>(os, any_value))
if(!out_to_stream<double>(os, any_value))
if(!out_to_stream<bool>(os, any_value))
if(!out_to_stream<std::string>(os, any_value))
os<<"{unknown}"; // all cast are failed, an unknown type of any
return os;
}
And then for a value_type:
std::ostream& operator<<(std::ostream& os, const boost::program_options::variable_value& cmdline_val)
{
if(cmdline_val.empty()){
os << "<empty>";
} else {
os<<cmdline_val.value();
if(cmdline_val.defaulted())
os << "(default)";
}
return os;
}
The list of type switches proposed in other answers can be improved with a loop over a type list using Boost MPL (see documentation of mpl::for_each and mpl::vector). The following code defines an operator<< for any boost::any that is given in the type list SupportedTypes and throws an exception otherwise.
#include <stdexcept>
#include <iostream>
#include <string>
#include <cstdint>
#include <boost/any.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/vector.hpp>
class StreamInserter
{
private:
std::ostream& os_;
const boost::any &v_;
mutable bool has_printed_;
public:
struct UnsupportedType {};
StreamInserter(std::ostream& os, const boost::any &v)
: os_(os), v_(v), has_printed_(false) {}
template <typename T>
void operator()(const T&) const
{
if (!has_printed_ && v_.type() == typeid(T))
{
os_ << boost::any_cast<T>(v_);
has_printed_ = true;
}
}
void operator()(const UnsupportedType&) const
{
if (!has_printed_)
throw std::runtime_error("unsupported type");
}
};
std::ostream& operator<<(std::ostream& os, const boost::any& v)
{
typedef boost::mpl::vector<float, double, int8_t, uint8_t, int16_t, uint16_t,
int32_t, uint32_t, int64_t, uint64_t, std::string, const char*,
StreamInserter::UnsupportedType> SupportedTypes;
StreamInserter si(os, v);
boost::mpl::for_each<SupportedTypes>(si);
return os;
}
int main(int, char**)
{
std::cout << boost::any(42.0) << std::endl;
std::cout << boost::any(42) << std::endl;
std::cout << boost::any(42UL) << std::endl;
std::cout << boost::any("42") << std::endl;
std::cout << boost::any(std::string("42")) << std::endl;
std::cout << boost::any(bool(42)) << std::endl; // throws exception
}
I think you have to cover each possible case of objects you have to print... Or use boost::variant.
EDIT: Sorry, I thought I shall write WHY.
The reason why I think that is because, looking at any source code, it seems to rely on the fact that YOU provide the types when inserting and getting data. When you insert, data is automatically detected by the compiler, so you don't have to specify it. But when you get the data, you shall use any_cast, because you're not sure of the data type you're getting.
If it worked in a different way and data type was sure, I think that would be no need for any_cast :)
Instead, variant have a limited set of possible data types, and this information is somewhat registered, giving you the ability to iterate in a generic way a variant container.
If you need this kind of manipulation - iterating a generic set of values - I think you shall use variant.
Try using xany https://sourceforge.net/projects/extendableany/?source=directory xany class allows to add new methods to any's existing functionality. By the way there is a example in documentation which does exactly what you want.
Rather than re-writing my class to use boost::spirit::hold_any, I created a way to stream boost::any, similar to what manifest suggested, but just in one place.
ostream& operator<<(ostream& _os, const boost::any& _any)
{
// only define simple type conversions
if (_any.type() == typeid(int))
_os << boost::any_cast<int>(_any);
/*any other types you use...*/
}
Rather cumbersome, but it allows me to stream a boost::any variable anywhere in my code.
How about being able to construct a boost::spirit::hold_any from a boost:any?
A little late for this party, but anyone that may be interested can also use std::tuple and a std::for_each-like template that iterates over a tuple.
This is based on the answer from ingomueller.net in this thread.
I had a recent case where I created a property map (reading configuration values, mainly fundamental types, from an XML file and inserting them into an std::unordered_map, where the value type is of type any. For debugging purposes I wanted to be able to print the entire map with its keys and values along with the type of the value.
In that project I am not using Boost at all, I used my own any implementation, but its very similar to boost::any.
The insertion operator basically looks like this:
template <typename TChar>
inline std::basic_ostream<TChar>&
operator<< (std::basic_ostream<TChar>& os, const sl::common::any& v)
{
// Types that we support with sl::common::any.
std::tuple<
float, double, bool,
int8_t, uint8_t,
int16_t, uint16_t,
int32_t, uint32_t,
int64_t, uint64_t,
std::wstring, const wchar_t*,
StreamInserter::UnsupportedType> t;
// Prepare ostream for printing a value of type any
StreamInserter si(os, v);
// Iterate over all types in tuple t. If the last type(UnsupportedType) is
// reached, given v is unsupported.
for_each(t, si);
return os;
}
The for_each template looks like this (C++14):
template <typename Tuple, typename F, std::size_t ...Indices>
constexpr void for_each_impl(Tuple&& tuple, F&& f, std::index_sequence<Indices...>) {
using swallow = int[];
(void)swallow{1,
(f(std::get<Indices>(std::forward<Tuple>(tuple))), void(), int{})...
};
}
template <typename Tuple, typename F>
constexpr void for_each(Tuple&& tuple, F&& f) {
constexpr std::size_t N = std::tuple_size<std::remove_reference_t<Tuple>>::value;
for_each_impl(std::forward<Tuple>(tuple), std::forward<F>(f),
std::make_index_sequence<N>{});
}
With this just use the StreamInserter class or something similar shown in Ingos answer.
Hope this helps.