fork(22) download
  1. #include <type_traits>
  2.  
  3. template <typename C, typename F, typename = void>
  4. struct is_call_possible : public std::false_type {};
  5.  
  6. template <typename C, typename R, typename... A>
  7. struct is_call_possible<C, R(A...),
  8. typename std::enable_if<
  9. std::is_same<R, void>::value ||
  10. std::is_convertible<decltype(
  11. std::declval<C>().operator()(std::declval<A>()...)
  12. ), R>::value
  13. >::type
  14. > : public std::true_type {};
  15.  
  16. // Demo
  17.  
  18. #include <string>
  19.  
  20. struct Foo
  21. {
  22. void operator()(double) const {}
  23. void operator()(std::string) const {}
  24. };
  25.  
  26. struct Bar : Foo
  27. {
  28. int operator()(int)
  29. {
  30. return 0;
  31. }
  32. };
  33.  
  34. static_assert(is_call_possible<Foo, void(double)>::value, "?");
  35. static_assert(is_call_possible<Foo, void(int)>::value, "?");
  36. static_assert(is_call_possible<Foo, void(const char*)>::value, "?");
  37. static_assert(!is_call_possible<Foo, void(void*)>::value, "?");
  38. static_assert(is_call_possible<Bar, void(double)>::value, "?");
  39. static_assert(is_call_possible<Bar, void(int)>::value, "?");
  40. static_assert(!is_call_possible<Bar, void(const char*)>::value, "?");
  41. static_assert(!is_call_possible<Bar, void(void*)>::value, "?");
  42. static_assert(is_call_possible<Bar, int(int)>::value, "?");
  43.  
  44. static_assert(is_call_possible<Bar, double(int)>::value, "?");
  45. static_assert(!is_call_possible<Bar, std::string(int)>::value, "?");
  46. static_assert(!is_call_possible<Bar, void()>::value, "?");
  47.  
  48. int main() {}
  49.  
  50.  
Success #stdin #stdout 0s 2892KB
stdin
Standard input is empty
stdout
Standard output is empty