fork download
  1. #include <iostream>
  2. #include <type_traits>
  3. #include <sstream>
  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 const any_t any_t::operator+(const any_t &other) const;
  14.  
  15. yes& test( any_t&, any_t );
  16. no test( no );
  17.  
  18. template<typename T>
  19. struct has_insertion_operator {
  20. static any_t& a;
  21. static any_t& b;
  22. static T const &t;
  23. static bool const value = sizeof( test(a + b) ) == sizeof( yes );
  24. };
  25. }
  26.  
  27. template<typename T>
  28. struct has_insertion_operator :
  29. has_insertion_operator_impl::has_insertion_operator<T> {
  30. };
  31.  
  32. template <typename T,
  33. typename std::enable_if<
  34. has_insertion_operator<T>::value, T>::type* = nullptr>
  35. void print(T lhs, T rhs) {
  36. std::cout << lhs + rhs << std::endl;
  37. }
  38.  
  39. template <typename T,
  40. typename std::enable_if<
  41. !has_insertion_operator<T>::value, T>::type* = nullptr>
  42. void print(T lhs, T rhs) {
  43. std::cout << 42 << std::endl;
  44. }
  45.  
  46. struct Foo
  47. {
  48. public:
  49. Foo() : val(0) { }
  50. Foo(int v) : val(v) { }
  51. ~Foo() { }
  52.  
  53. int value() const { return val; }
  54.  
  55. Foo & operator+=(const Foo &rhs);
  56. const Foo operator+(const Foo &other) const;
  57. private:
  58. int val;
  59. };
  60.  
  61. Foo & Foo::operator+=(const Foo &rhs) {
  62. this->val += rhs.value();
  63.  
  64. return *this;
  65. }
  66.  
  67. const Foo Foo::operator+(const Foo &other) const {
  68. Foo result = *this; // Make a copy of myself. Same as MyClass result(*this);
  69. result += other; // Use += to add other to the copy.
  70. return result; // All done!
  71. }
  72.  
  73. int main()
  74. {
  75. print(42, 42);
  76. print(Foo(42), Foo(42));
  77. return 0;
  78. }
Compilation error #stdin compilation error #stdout 0s 2852KB
stdin
Standard input is empty
compilation info
prog.cpp:13:18: error: expected initializer before ‘any_t’
prog.cpp:23:48: error: no match for ‘operator+’ in ‘has_insertion_operator_impl::has_insertion_operator<T>::a + has_insertion_operator_impl::has_insertion_operator<T>::b’
prog.cpp: In function ‘int main()’:
prog.cpp:75:17: error: no matching function for call to ‘print(int, int)’
prog.cpp:75:17: note: candidates are:
prog.cpp:35:6: note: template<class T, typename std::enable_if<has_insertion_operator<T>::value, T>::type* <anonymous> > void print(T, T)
prog.cpp:35:6: note:   template argument deduction/substitution failed:
prog.cpp:34:55: note: invalid template non-type parameter
prog.cpp:42:6: note: template<class T, typename std::enable_if<(! has_insertion_operator<T>::value), T>::type* <anonymous> > void print(T, T)
prog.cpp:42:6: note:   template argument deduction/substitution failed:
prog.cpp:41:56: error: in argument to unary !
prog.cpp:41:56: note: invalid template non-type parameter
prog.cpp:76:27: error: no matching function for call to ‘print(Foo, Foo)’
prog.cpp:76:27: note: candidates are:
prog.cpp:35:6: note: template<class T, typename std::enable_if<has_insertion_operator<T>::value, T>::type* <anonymous> > void print(T, T)
prog.cpp:35:6: note:   template argument deduction/substitution failed:
prog.cpp:34:55: note: invalid template non-type parameter
prog.cpp:42:6: note: template<class T, typename std::enable_if<(! has_insertion_operator<T>::value), T>::type* <anonymous> > void print(T, T)
prog.cpp:42:6: note:   template argument deduction/substitution failed:
prog.cpp:41:56: error: in argument to unary !
prog.cpp:41:56: note: invalid template non-type parameter
stdout
Standard output is empty