Skip to content

Instantly share code, notes, and snippets.

@GeeLaw
Created August 13, 2018 10:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GeeLaw/a93e60f05c0257278f36b199d9987f53 to your computer and use it in GitHub Desktop.
Save GeeLaw/a93e60f05c0257278f36b199d9987f53 to your computer and use it in GitHub Desktop.
Use SFINAE to detect whether to_string is present.
#include<string>
#include<iostream>
#include<utility>
#include<type_traits>
template <typename T, typename TType, bool value =
std::is_same<std::string, decltype(to_string(std::forward<T>(*(T *)nullptr)))>::value
>
struct has_to_string { };
template <typename T, typename TType>
struct has_to_string<T, TType, true>
{
typedef TType type;
};
template <typename T, typename TType = void>
using has_to_string_t = typename has_to_string<T, TType>::type;
template <typename T>
has_to_string_t<T, std::ostream &> operator << (std::ostream &ost, T &&value)
{
return ost << to_string(std::forward<T>(value));
}
struct T1 { };
struct T2 { };
std::string to_string(T1)
{
return "T1";
}
namespace NS
{
struct T3 { };
std::string to_string(T3)
{
return "T3";
}
}
int main()
{
// The following wouldn't work because
// ADL won't find std::to_string.
// This is fine since std::to_string only
// deals with some basic types, which are
// already covered by std::operator <<.
// ::operator << <int>(std::cout, 1) << std::endl;
std::cout << 1 << std::endl;
std::cout << T1() << std::endl;
// Does not compile:
// std::cout << T2() << std::endl;
std::cout << NS::T3() << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment