fork(1) download
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. /// function traits for member functions
  5. // gives you the class_type, return_type and arguments tuple for any member function (const and not const)
  6. template<typename T>
  7. struct func_traits{
  8. static const bool is_const_call = false;
  9. typedef void class_type;
  10. typedef void return_type;
  11. typedef void args_tuple;
  12. };
  13. // specialization for non const call member functions
  14. template < typename TClass ,typename TRet, typename ... TArgs>
  15. struct func_traits<TRet(TClass::*)(TArgs...)>
  16. {
  17. static const bool is_const_call = false;
  18. typedef TClass class_type;
  19. typedef TRet return_type;
  20. typedef std::tuple<TArgs...> args_tuple;
  21. };
  22. // specialization for const call member function
  23. template < typename TClass, typename TRet, typename ... TArgs>
  24. struct func_traits<TRet(TClass::*)(TArgs...)const>
  25. {
  26. static const bool is_const_call = true;
  27. typedef TClass class_type;
  28. typedef TRet return_type;
  29. typedef std::tuple<TArgs...> args_tuple;
  30. };
  31.  
  32. // checks wether a single call operator exists by sfinae ideom
  33. template<typename T>
  34. struct is_callable{
  35.  
  36. private:
  37. // if the argument type is deducable this function is used
  38. template<typename TX = T>
  39. static char check(typename func_traits<decltype(&TX::operator())>::class_type);
  40. // else this function is used
  41. static double check(...);
  42. static T t;
  43. // if first function is used the call operator exists and the size is sizeof(char) instead of sizeof(double)
  44. enum{ _value = sizeof(check(t)) == sizeof(char) };
  45. public:
  46. const static bool value = _value;
  47. };
  48.  
  49.  
  50. int main() {
  51. // B is a functor class, A not callable
  52. class B{ public:void operator()(int i)const{} };
  53. class A{};
  54. // this order works in MSVC 2013
  55. // static_assert(is_callable<B>::value == true, "should be true");
  56. // static_assert(is_callable<A>::value == false, "should be false");
  57.  
  58. // this order does not work in MSVC 2013
  59. static_assert(is_callable<A>::value == false, "should be false");
  60. static_assert(is_callable<B>::value == true, "should be true");
  61.  
  62. //
  63. return 0;
  64. }
  65.  
  66.  
Success #stdin #stdout 0s 3292KB
stdin
Standard input is empty
stdout
Standard output is empty