I am trying to write a stream statement for std containers, mainly for debugging purposes.
I have the following code:
#include <type_traits> #include <iostream> #include <ostream> #include <iterator> #include <algorithm> #include <functional> #include <vector> #include <set> #include <deque> template<typename Container> struct is_container { typedef char no; typedef long yes; template<typename A, A, A> struct is_of_type; template<typename T> static yes& is_cont( is_of_type < typename T::iterator(T::*)(), &T::begin, &T::end >*); template<typename T> static no& is_cont(...); //any other template<typename C, bool B> struct is_class_is_container { const static bool value=sizeof( is_cont<C>(nullptr) )==sizeof(yes); }; template<typename C> struct is_class_is_container<C, false> { const static bool value=false; }; const static bool value = is_class_is_container < Container, std::is_class<Container>::value >::value; }; template<typename T> typename std::enable_if < is_container<T>::value, std::ostream >::type& operator<<(std::ostream& os, const T& a) { os << '['; std::copy(a.begin(), a.end(), std::ostream_iterator<typename T::value_type>(os, ", ")); os << ']'; return os; }
I know that this is far from ideal (constructive comments appreciated), but the problem I came across is that it works fine for vector, deque and list, but not suitable for sets, I don't know why, since sets still have iterator interfaces start and end.
Thanks.
EDIT: checked on g ++ (GCC) 4.6.2 2012012 version clang 3.0
EDIT2: I got the job using decltype, but this is not optimal, because now I can not say that it does what I expect (return an iterator).
I don’t know exactly what a set is, first of all, maybe if someone has a way to debug TMP, that would be good.