fork download
  1. // Example program
  2. #include <iostream>
  3. #include <string>
  4.  
  5. namespace mpl {
  6.  
  7. template<typename ...>
  8. struct void_type
  9. {
  10. using type = void;
  11. };
  12.  
  13. template<typename ...T>
  14. using void_t = typename void_type<T...>::type;
  15.  
  16. } // namespace mpl
  17.  
  18. #define CAN_CALL_METHOD(NAME) \
  19. namespace internal { \
  20. template<typename T, typename ...Args> \
  21. using result_of_call_method_##NAME = decltype( \
  22.   std::declval<T>().NAME(std::declval<Args>()...)); \
  23. } \
  24. template<typename T, typename Signature, typename = void> \
  25. struct can_call_method_##NAME: std::false_type \
  26. {}; \
  27. template<typename T, typename ...Args> \
  28. struct can_call_method_##NAME<T, void(Args...), \
  29.   mpl::void_t<internal::result_of_call_method_##NAME<T, Args...>> \
  30.   >: std::true_type \
  31. {}; \
  32. template<typename T, typename R, typename ...Args> \
  33. struct can_call_method_##NAME<T, R(Args...), \
  34.   typename std::enable_if<!std::is_void<R>::value && \
  35.   std::is_convertible<internal::result_of_call_method_##NAME<T, Args...>, R \
  36.   >::value \
  37.   >::type \
  38.   >: std::true_type \
  39. {};
  40.  
  41. CAN_CALL_METHOD(hello);
  42.  
  43. struct Foo {
  44. template <typename T>
  45. void hello(T&) {}
  46. };
  47.  
  48. struct Foo1 {
  49. };
  50.  
  51. int main()
  52. {
  53. std::cout << std::boolalpha;
  54. std::cout << can_call_method_hello<Foo, void(int&)>::value << std::endl;
  55. std::cout << can_call_method_hello<Foo1, void(int&)>::value << std::endl;
  56. }
  57.  
Success #stdin #stdout 0s 3412KB
stdin
Standard input is empty
stdout
true
false