In this answer I define a template based on the type's is_arithmetic property:
template<typename T> enable_if_t<is_arithmetic<T>::value, string> stringify(T t){
return to_string(t);
}
template<typename T> enable_if_t<!is_arithmetic<T>::value, string> stringify(T t){
return static_cast<ostringstream&>(ostringstream() << t).str();
}
dyp suggests that rather than the is_arithmetic property of the type, that whether to_string is defined for the type be the template selection criteria. This is clearly desirable, but I don't know a way to say:
If
std::to_stringis not defined then use theostringstreamoverload.
Declaring the to_string criteria is simple:
template<typename T> decltype(to_string(T{})) stringify(T t){
return to_string(t);
}
It's the opposite of that criteria that I can't figure out how to construct. This obviously doesn't work, but hopefully it conveys what I'm trying to construct:
template<typename T> enable_if_t<!decltype(to_string(T{})::value, string> (T t){
return static_cast<ostringstream&>(ostringstream() << t).str();
}
Using Walter Brown's void_t:
template <typename...>
using void_t = void;
It's very easy to make such a type trait:
template<typename T, typename = void>
struct has_to_string
: std::false_type { };
template<typename T>
struct has_to_string<T,
void_t<decltype(std::to_string(std::declval<T>()))>
>
: std::true_type { };
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