So with SFINAE and c++11, it is possible to implement two different template functions based on whether one of the template parameters can be substituted.
For exampl
I find the void_t trick to be usually preferable to the traditional SFINAE method shown in the other answer.
template using void_t = void; // now in the C++17 working paper!
// GCC <= 4.9 workaround:
// template struct voider { using type = void; };
// template using void_t = typename voider::type;
template
struct is_ostreamable : std::false_type {};
template
struct is_ostreamable() <<
std::declval())>> : std::true_type {};
The partial specialization is selected if and only if the expression is well-formed.
Demo.
Note that the & in std::declval is important, because otherwise std::declval is an rvalue and you'll get ostream's catchall rvalue stream insertion operator, and report that everything is streamable.
The above code checks for an operator<< that can accept a T rvalue . If you want to check for one that accepts an lvalue T, then use std::declval.