Я пытаюсь написать оператор потока для контейнеров std, главным образом для отладки.
У меня есть следующий код:
#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;
}
Я знаю, что это далеко отидеально (конструктивные комментарии приветствуются), но проблема, с которой я столкнулся, заключается в том, что он отлично работает для вектора, deque и list, но не подходит для наборов, я не знаю почему, потому что наборы все еще имеют интерфейсы итератора, начинающиеся и заканчивающиеся.
Спасибо.
РЕДАКТИРОВАТЬ: протестировано на g ++ (GCC) 4.6.2 2012012 clang версия 3.0
РЕДАКТИРОВАТЬ2: я вроде как работает с использованием decltype, однако это неоптимально, потому что теперь яне могу утверждать, что он выполняет то, что я ожидаю (возвращаю итератор).
Я точно не знаю, какой набор был возвращен в первую очередь, возможно, если у кого-то есть способ отладки TMP, который быбудь хорошим.