fork(1) download
  1. #include <iostream>
  2. #include <type_traits>
  3.  
  4. // template funcName should exist
  5. #define HAS_TEMPLATED_FUNC(traitsName, funcName, Prototype) \
  6.   template<typename T> \
  7.   class traitsName \
  8.   typedef char yes[1]; \
  9.   typedef struct {char dummy[2];} no ; \
  10.   template <typename U, U> struct type_check; \
  11.   template <typename U = T> static yes &chk(type_check<Prototype, &funcName<U>>*); \
  12.   template <typename > static no &chk(...); \
  13.   public: \
  14.   static bool const value = sizeof(chk<T>(0)) == sizeof(yes); \
  15.   }
  16.  
  17. //A sequence container type
  18. class Array_T{};
  19.  
  20. //A type trait for that particular sequence container
  21. template <typename T> struct Is_Array { static const bool value = false; };
  22. template <> struct Is_Array<Array_T> { static const bool value = true; };
  23.  
  24. //A type trait to identify all of the sequence containers
  25. template <typename T> struct Is_A_Sequence_Container { static const bool value = Is_Array<T>::value
  26. /* would probably "or" together more sequence types, but we only have Array_T in this example */;};
  27.  
  28. //A type trait to identify all of the data structures
  29. template <typename T> struct Is_A_Data_Structure { static const bool value = Is_A_Sequence_Container<T>::value
  30. /* would probably "or" together more data structure types, but we only have sequence containers in this example */;};
  31.  
  32.  
  33.  
  34. //NOTE: This function MAY OR MAY NOT actually appear in the source code
  35. //This function handles all sequence types
  36. template<class T, typename std::enable_if<Is_A_Sequence_Container<T>::value,int>::type=0>
  37. void function(T t) {
  38. std::cout << "sequence container" << std::endl;
  39. return;
  40. }
  41.  
  42.  
  43. // this assumes that any template 'function' exists
  44. // (Do you have version for `data structure` ?)
  45. // or else create a dummy struct and then
  46. // template <T>
  47. // typename std::enable_if<std::is_same<T, dummy>::value>::type function(dummy) {}
  48. HAS_TEMPLATED_FUNC(isFunctionExist_Specialized, function, void (*)(T));
  49.  
  50. //This function handles all data structures; assuming a more specific function does not exist(*cough* the one above it)
  51. template<class T, typename std::enable_if<Is_A_Data_Structure<T>::value, int>::type = 0,
  52. typename std::enable_if<!isFunctionExist_Specialized<T>::value, int>::type = 0>>
  53. void function(T t) {
  54. std::cout << "data structure" << std::endl;
  55. return;
  56. }
  57.  
  58. int main(){
  59.  
  60. function(Array_T{});
  61. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:7:5: error: template declaration of ‘typedef’
     class traitsName                                                                 \
     ^
prog.cpp:48:1: note: in expansion of macro ‘HAS_TEMPLATED_FUNC’
 HAS_TEMPLATED_FUNC(isFunctionExist_Specialized, function, void (*)(T));
 ^
prog.cpp:11:32: error: expected type-specifier before ‘T’
         template <typename U = T> static yes &chk(type_check<Prototype, &funcName<U>>*); \
                                ^
prog.cpp:48:1: note: in expansion of macro ‘HAS_TEMPLATED_FUNC’
 HAS_TEMPLATED_FUNC(isFunctionExist_Specialized, function, void (*)(T));
 ^
prog.cpp:11:32: error: expected ‘>’ before ‘T’
         template <typename U = T> static yes &chk(type_check<Prototype, &funcName<U>>*); \
                                ^
prog.cpp:48:1: note: in expansion of macro ‘HAS_TEMPLATED_FUNC’
 HAS_TEMPLATED_FUNC(isFunctionExist_Specialized, function, void (*)(T));
 ^
prog.cpp:11:42: error: ‘yes’ does not name a type
         template <typename U = T> static yes &chk(type_check<Prototype, &funcName<U>>*); \
                                          ^
prog.cpp:48:1: note: in expansion of macro ‘HAS_TEMPLATED_FUNC’
 HAS_TEMPLATED_FUNC(isFunctionExist_Specialized, function, void (*)(T));
 ^
prog.cpp:13:5: error: expected unqualified-id before ‘public’
     public:                                                                          \
     ^
prog.cpp:48:1: note: in expansion of macro ‘HAS_TEMPLATED_FUNC’
 HAS_TEMPLATED_FUNC(isFunctionExist_Specialized, function, void (*)(T));
 ^
prog.cpp:15:5: error: expected declaration before ‘}’ token
     }
     ^
prog.cpp:48:1: note: in expansion of macro ‘HAS_TEMPLATED_FUNC’
 HAS_TEMPLATED_FUNC(isFunctionExist_Specialized, function, void (*)(T));
 ^
stdout
Standard output is empty