fork download
  1. #include <cstdint>
  2. #include <type_traits>
  3.  
  4. #define DEFINE_HAS_MEMBER(traitsName, memberName) \
  5.   template <typename U> \
  6.   class traitsName \
  7.   { \
  8.   private: \
  9.   struct Fallback { int memberName; }; \
  10.   struct Dummy {}; \
  11.   template<typename T, bool is_a_class = std::is_class<T>::value> \
  12.   struct identity_for_class_or_dummy { using type = Dummy; }; \
  13.   template<typename T> \
  14.   struct identity_for_class_or_dummy<T, true> { using type = T; }; \
  15.   \
  16.   template <typename Base> \
  17.   struct Derived : Base, Fallback {}; \
  18.   template<typename T, T> struct helper; \
  19.   template<typename T> \
  20.   static std::uint8_t \
  21.   check(helper<int (Fallback::*), \
  22.   &Derived<typename identity_for_class_or_dummy<T>::type>::memberName>*); \
  23.   template<typename T> static std::uint16_t check(...); \
  24.   public: \
  25.   static \
  26.   constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint16_t); \
  27.   }
  28.  
  29. DEFINE_HAS_MEMBER(has_foo, foo);
  30.  
  31. class C{ public: char foo; };
  32. class D : public C {};
  33. class E {};
  34.  
  35. static_assert(has_foo<C>::value, "");
  36. static_assert(has_foo<D>::value, "");
  37. static_assert(!has_foo<E>::value, "");
  38. static_assert(!has_foo<int>::value, "");
  39.  
  40. int main()
  41. {
  42. return 0;
  43. }
  44.  
Success #stdin #stdout 0s 3292KB
stdin
Standard input is empty
stdout
Standard output is empty