fork download
  1. #include <type_traits>
  2.  
  3. template <typename T>
  4. struct Class {
  5. Class(T const &t) { }
  6. };
  7.  
  8. template <typename T_Lhs, typename T_Rhs>
  9. struct ClassAnd {
  10. ClassAnd(T_Lhs const &lhs, T_Rhs const &rhs) { }
  11. };
  12.  
  13. // Addition of ClassNot and the appropriate operators causes an ambiguity in operator&.
  14. template <typename T>
  15. struct ClassNot {
  16. ClassNot(T const &t) : value(t) { }
  17. T value;
  18. };
  19.  
  20. template <class T>
  21. struct IsClassNot : std::false_type
  22. {};
  23.  
  24. template <class T>
  25. struct IsClassNot<ClassNot<T>> : std::true_type
  26. {};
  27.  
  28.  
  29. template <typename T_Lhs, typename T_Rhs>
  30. struct ClassAndNot {
  31. ClassAndNot(T_Lhs const &lhs, T_Rhs const &rhs) { }
  32. };
  33.  
  34. template <typename T_Lhs, typename T_Rhs>
  35. ClassAndNot<T_Lhs, T_Rhs> operator&(T_Lhs const &lhs, ClassNot<T_Rhs> const &rhs) {
  36. return ClassAndNot<T_Lhs, T_Rhs>(lhs, rhs.value);
  37. }
  38.  
  39. template <typename T_Rhs>
  40. ClassNot<T_Rhs> operator!(T_Rhs const &rhs) {
  41. return ClassNot<T_Rhs>(rhs);
  42. }
  43.  
  44.  
  45.  
  46. template <typename T, typename T_Rhs>
  47. typename std::enable_if<!IsClassNot<T_Rhs>::value,
  48. ClassAnd<Class<T>, T_Rhs>>::type operator&(Class<T> const &lhs, T_Rhs const &rhs) {
  49. return ClassAnd<Class<T>, T_Rhs>(lhs, rhs);
  50. }
  51.  
  52. template <typename T0, typename T1, typename T_Rhs>
  53. typename std::enable_if<!IsClassNot<T_Rhs>::value,
  54. ClassAnd<ClassAnd<T0, T1>, T_Rhs>>::type operator&(ClassAnd<T0, T1> const &lhs, T_Rhs const &rhs) {
  55. return ClassAnd<ClassAnd<T0, T1>, T_Rhs>(lhs, rhs);
  56. }
  57.  
  58. // Sample usage.
  59. int main() {
  60. Class<int> a(42);
  61. Class<double> b(3.14);
  62. auto c = a & !b;
  63. }
  64.  
Success #stdin #stdout 0s 3292KB
stdin
Standard input is empty
stdout
Standard output is empty