I've seen types that have corresponding to_string()
function, but haven't overloaded operator<<()
. So, when inserting to stream, one has to << to_string(x)
which is verbose. I'm wondering whether it's possible to write a generic function that users operator<<()
if supported and falls back to << to_string()
if not.
SFINAE is overkill, use ADL.
The trick is to make sure that an operator<<
is available, not necessarily the one supplied by the type definition:
namespace helper {
template<typename T> std::ostream& operator<<(std::ostream& os, T const& t)
{
return os << to_string(t);
}
}
using helper::operator<<;
std::cout << myFoo;
This trick is commonly used in generic code which needs to choose between std::swap<T>
and a specialized Foo::swap(Foo::Bar&, Foo::Bar&)
.
Try
template <typename T>
void print_out(T t) {
print_out_impl(std::cout, t, 0);
}
template <typename OS, typename T>
void print_out_impl(OS& o, T t,
typename std::decay<decltype(
std::declval<OS&>() << std::declval<T>()
)>::type*) {
o << t;
}
template <typename OS, typename T>
void print_out_impl(OS& o, T t, ...) {
o << t.to_string();
}
LIVE
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With