fork download
  1. #include <type_traits> // To use 'std::integral_constant'.
  2. #include <iostream> // To use 'std::cout'.
  3. #include <iomanip> // To use 'std::boolalpha'.
  4. #include <map>
  5. #include <vector>
  6.  
  7. #define GENERATE_HAS_MEMBER(member) \
  8.   \
  9. template < class T > \
  10. class HasMember_##member \
  11. { \
  12. private: \
  13.   using Yes = char[2]; \
  14.   using No = char[1]; \
  15.   \
  16.   struct Fallback { int member; }; \
  17.   struct Derived : T, Fallback { }; \
  18.   \
  19.   template < class U > \
  20.   static No& test ( decltype(U::member)* ); \
  21.   template < typename U > \
  22.   static Yes& test ( U* ); \
  23.   \
  24. public: \
  25.   static constexpr bool RESULT = sizeof(test<Derived>(nullptr)) == sizeof(Yes); \
  26. }; \
  27.   \
  28. template < class T > \
  29. struct has_member_##member \
  30. : public std::integral_constant<bool, HasMember_##member<T>::RESULT> \
  31. { \
  32. };
  33.  
  34.  
  35. GENERATE_HAS_MEMBER(find) // Creates 'has_member_func'.
  36.  
  37. struct B
  38. {
  39. double find ( const char* );
  40. };
  41.  
  42.  
  43. int main ( )
  44. {
  45. std::cout << std::boolalpha
  46. << "\n" "'find' in 'B' : "
  47. << has_member_find<B>() // <type_traits>-like interface.
  48. << "\n" "'find' in 'std::map' : "
  49. << has_member_find<std::map<int,int> >() // Implicitly convertible to 'bool'.
  50. << "\n" "'find' in 'std::vector' : "
  51. << has_member_find<std::vector<int> >() // Implicitly convertible to 'bool'.
  52. << "\n";
  53. }
Success #stdin #stdout 0s 16048KB
stdin
Standard input is empty
stdout
'find' in 'B' : true
'find' in 'std::map' : true
'find' in 'std::vector' : false