I am trying to write a stream operator for std containers, mainly for the purpose of debugging.
I have the following code:
#include #include #include #include #include #include #include #include #include template struct is_container { typedef char no; typedef long yes; template struct is_of_type; template static yes& is_cont( is_of_type < typename T::iterator(T::*)(), &T::begin, &T::end >*); template static no& is_cont(...); //any other template struct is_class_is_container { const static bool value=sizeof( is_cont(nullptr) )==sizeof(yes); }; template struct is_class_is_container { const static bool value=false; }; const static bool value = is_class_is_container < Container, std::is_class::value >::value; }; template typename std::enable_if < is_container::value, std::ostream >::type& operator<<(std::ostream& os, const T& a) { os << '['; std::copy(a.begin(), a.end(), std::ostream_iterator(os, ", ")); os << ']'; return os; } ,>
I am aware this is far from perfect (constructive comments appreciated) but the problem I am having is that it works great for vector, deque and list but fails to match on sets, I don't know why because sets still have the iterator interfaces begin and end.
Thanks.
EDIT: tested on g++ (GCC) 4.6.2 2012012 clang version 3.0
EDIT2: I got it sort of working using decltype however that is sub optimal because now I can't assert that it does what I expect (return an iterator) to.
I don't exactly know what the set was return in the first place, maybe if someone has a way of debugging TMP that would be good.