fork download
  1. #include <type_traits>
  2. #include <cstdint>
  3.  
  4. #define DEFINE_HAS_SIGNATURE(traitsName, funcName, signature) \
  5.   template <typename U> \
  6.   class traitsName \
  7.   { \
  8.   private: \
  9.   template<typename T, T> struct helper; \
  10.   template<typename T> \
  11.   static std::uint8_t check(helper<signature, &funcName>*); \
  12.   template<typename T> static std::uint16_t check(...); \
  13.   public: \
  14.   static \
  15.   constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint8_t); \
  16.   }
  17.  
  18. DEFINE_HAS_SIGNATURE(has_X, T::X, bool (T::*)());
  19. DEFINE_HAS_SIGNATURE(has_Y, T::Y, bool (T::*)());
  20.  
  21. template <typename T>
  22. typename std::enable_if<has_X<T>::value && has_Y<T>::value, bool>::type
  23. func(T a)
  24. {
  25. if(a.X())
  26. return a.Y();
  27. return false;
  28. }
  29.  
  30. template <typename T>
  31. typename std::enable_if<!has_X<T>::value || !has_Y<T>::value, bool>::type
  32. func(T /*a*/)
  33. {
  34. return false;
  35. }
  36.  
  37. struct A {
  38. bool X() {return true;}
  39. bool Y() {return true;}
  40. };
  41.  
  42. struct B {
  43. };
  44.  
  45. int main()
  46. {
  47. func<A>(A{});
  48. func<B>(B{});
  49.  
  50. return 0;
  51. }
  52.  
Success #stdin #stdout 0s 3292KB
stdin
Standard input is empty
stdout
Standard output is empty