I am trying to write a stream operator for std containers, mainly for the purpose of debugging.
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 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.
 
     
    