fork(1) download
  1. #include <iostream>
  2. #include <string>
  3. #include <type_traits>
  4.  
  5. namespace has_insertion_operator_impl {
  6. typedef char no;
  7. typedef char yes[2];
  8.  
  9. struct any_t {
  10. template<typename T> any_t( T const& );
  11. };
  12.  
  13. no operator<<( std::ostream const&, any_t const& );
  14.  
  15. yes& test( std::ostream& );
  16. no test( no );
  17.  
  18. template<typename T>
  19. struct has_insertion_operator {
  20. static std::ostream &s;
  21. static T const &t;
  22. static bool const value = sizeof( test(s << t) ) == sizeof( yes );
  23. };
  24. }
  25.  
  26. template<typename T>
  27. struct has_insertion_operator :
  28. has_insertion_operator_impl::has_insertion_operator<T> {
  29. };
  30.  
  31. template <typename T,
  32. typename std::enable_if<has_insertion_operator<T>::value, T>::type* = nullptr>
  33. void print(T obj) {
  34. std::cout << "from print()" << std::endl;
  35. }
  36.  
  37. template <typename T,
  38. typename std::enable_if<!has_insertion_operator<T>::value, T>::type* = nullptr>
  39. void print(T obj) {
  40. std::cout << obj.to_string() << std::endl;
  41. }
  42.  
  43. struct Foo
  44. {
  45. public:
  46. friend std::ostream& operator<<(std::ostream & os, Foo const& foo);
  47. };
  48.  
  49. struct Bar
  50. {
  51. public:
  52. std::string to_string() const
  53. {
  54. return "from to_string()";
  55. }
  56. };
  57.  
  58. int main()
  59. {
  60. print<Foo>(Foo());
  61. print<Bar>(Bar());
  62.  
  63. //print<Bar>(Foo()); doesn't compile
  64. //print<Foo>(Bar()); doesn't compile
  65.  
  66. print(Foo());
  67. print(Bar());
  68.  
  69. print(42);
  70. print('a');
  71. print(std::string("Hi"));
  72. print("Hey");
  73. //print({1, 2, 3}); doesn't compile
  74. return 0;
  75. }
  76.  
Success #stdin #stdout 0s 3028KB
stdin
Standard input is empty
stdout
from print()
from to_string()
from print()
from to_string()
from print()
from print()
from print()
from print()