fork(1) download
  1. #include <functional>
  2. #include <utility>
  3. #include <iostream>
  4. #include <functional>
  5. using namespace std;
  6.  
  7. // For generic types that are functors, delegate to its 'operator()'
  8. template <typename T>
  9. struct function_traits
  10. : public function_traits<decltype(&T::operator())>
  11. {};
  12.  
  13. // for pointers to member function
  14. template <typename ClassType, typename ReturnType, typename... Args>
  15. struct function_traits<ReturnType(ClassType::*)(Args...) const> {
  16. enum { arity = sizeof...(Args) };
  17. typedef function<ReturnType (Args...)> f_type;
  18. };
  19.  
  20. // for pointers to member function
  21. template <typename ClassType, typename ReturnType, typename... Args>
  22. struct function_traits<ReturnType(ClassType::*)(Args...) > {
  23. enum { arity = sizeof...(Args) };
  24. typedef function<ReturnType (Args...)> f_type;
  25. };
  26.  
  27. // for function pointers
  28. template <typename ReturnType, typename... Args>
  29. struct function_traits<ReturnType (*)(Args...)> {
  30. enum { arity = sizeof...(Args) };
  31. typedef function<ReturnType (Args...)> f_type;
  32. };
  33.  
  34. template <typename L>
  35. static typename function_traits<L>::f_type make_function(L l){
  36. return (typename function_traits<L>::f_type)(l);
  37. }
  38.  
  39. //handles bind & multiple function call operator()'s
  40. template<typename ReturnType, typename... Args, class T>
  41. auto make_function(T&& t)
  42. -> std::function<decltype(ReturnType(t(std::declval<Args>()...)))(Args...)>
  43. {return {std::forward<T>(t)};}
  44.  
  45. //handles explicit overloads
  46. template<typename ReturnType, typename... Args>
  47. auto make_function(ReturnType(*p)(Args...))
  48. -> std::function<ReturnType(Args...)> {
  49. return {p};
  50. }
  51.  
  52. //handles explicit overloads
  53. template<typename ReturnType, typename... Args, typename ClassType>
  54. auto make_function(ReturnType(ClassType::*p)(Args...))
  55. -> std::function<ReturnType(Args...)> {
  56. return {p};
  57. }
  58.  
  59. // testing
  60. using namespace std::placeholders;
  61.  
  62. int foo(int x, int y, int z) { return x + y + z;}
  63. int foo1(int x, int y, int z) { return x + y + z;}
  64. float foo1(int x, int y, float z) { return x + y + z;}
  65.  
  66. int main () {
  67. //unambuiguous
  68. auto f0 = make_function(foo);
  69. auto f1 = make_function([](int x, int y, int z) { return x + y + z;});
  70. cout << make_function([](int x, int y, int z) { return x + y + z;})(1,2,3) << endl;
  71.  
  72. int first = 4;
  73. auto lambda_state = [=](int y, int z) { return first + y + z;}; //lambda with states
  74. cout << make_function(lambda_state)(1,2) << endl;
  75.  
  76. //ambuiguous cases
  77. auto f2 = make_function<int,int,int,int>(std::bind(foo,_1,_2,_3)); //bind results has multiple operator() overloads
  78. cout << f2(1,2,3) << endl;
  79. auto f3 = make_function<int,int,int,int>(foo1); //overload1
  80. auto f4 = make_function<float,int,int,float>(foo1); //overload2
  81.  
  82. return 0;
  83. }
Success #stdin #stdout 0s 3432KB
stdin
Standard input is empty
stdout
6
7
6