И это всё МОЁ

Вопрос к знатокам.

Хочу сделать вывод названий типов используя typeid(T).name() для выражений которые «не умеют» выводить своё значение в std::ostream.

Пытаюсь делать вот так:

#include <iostream>
#include <typeinfo>

template <typename T, typename = std::ostream&>
struct can_be_streamed : std::false_type {};

template <typename T>
struct can_be_streamed<T, decltype(std::declval<std::ostream&>() << std::declval<T>())> : std::true_type {};

template <typename S, typename T>
typename std::enable_if<!can_be_streamed<T>::value, S&>::type operator<<(S &s, const T &t)
{
return s << "type:" << typeid(t).name();
}

class A {};

std::ostream& operator<<(std::ostream &s, const A &;)
{
return s << "value::" /*<< ...*/;
}

class B {};

int main(void)
{
A a;
std::cout << a << std::endl;
B b;
std::cout << b << std::endl;
return EXIT_SUCCESS;
}

Есть несколько версий компиляторов и...

gcc 9.1.0 всё Ok.

clang 7.0.1 всё Ok.

А вот gcc 6.4.0 кричит:

v1.cpp: In substitution of 'template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, const std::error_code&;) [with _CharT = char; _Traits = std::char_traits<char>]':
v1.cpp:8:66: recursively required by substitution of 'template<class S, class T> typename std::enable_if<(! can_be_streamed<T>::value), S&>::type operator<<(S&, const T&;) [with S = std::basic_ostream<char>; T = char [8]]'
v1.cpp:8:66: required by substitution of 'template<class S, class T> typename std::enable_if<(! can_be_streamed<T>::value), S&>::type operator<<(S&, const T&;) [with S = std::basic_ostream<char>; T = char [8]]'
v1.cpp:20:17: required from here
v1.cpp:8:66: fatal error: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum)
struct can_be_streamed<T, decltype(std::declval<std::ostream&>() << std::declval<T>())> : std::true_type {};

Откуда рекурсия?

И что нужно подправить для gcc 6.4.0 что бы это починить?