fork(1) download
  1. /*
  2.  * This example show some ways of using std::function to call
  3.  * a) C-like function
  4.  * b) class-member function
  5.  * c) operator()
  6.  * d) lambda function
  7.  *
  8.  * Function call can be made:
  9.  * a) with right arguments
  10.  * b) argumens with different order, types and count
  11.  */
  12. #include <iostream>
  13. #include <functional>
  14. #include <iostream>
  15. #include <vector>
  16.  
  17. using std::cout;
  18. using std::endl;
  19. using namespace std::placeholders;
  20.  
  21.  
  22.  
  23. // simple function to be called
  24. double foo_fn(int x, float y, double z)
  25. {
  26. double res = x + y + z;
  27. std::cout << "foo_fn called with arguments: "
  28. << x << ", " << y << ", " << z
  29. << " result is : " << res
  30. << std::endl;
  31. return res;
  32. }
  33.  
  34. // structure with member function to call
  35. struct foo_struct
  36. {
  37. // member function to call
  38. double foo_fn(int x, float y, double z)
  39. {
  40. double res = x + y + z;
  41. std::cout << "foo_struct::foo_fn called with arguments: "
  42. << x << ", " << y << ", " << z
  43. << " result is : " << res
  44. << std::endl;
  45. return res;
  46. }
  47. // this member function has different signature - but it can be used too
  48. // please not that argument order is changed too
  49. double foo_fn_4(int x, double z, float y, long xx)
  50. {
  51. double res = x + y + z + xx;
  52. std::cout << "foo_struct::foo_fn_4 called with arguments: "
  53. << x << ", " << z << ", " << y << ", " << xx
  54. << " result is : " << res
  55. << std::endl;
  56. return res;
  57. }
  58. // overloaded operator() makes whole object to be callable
  59. double operator()(int x, float y, double z)
  60. {
  61. double res = x + y + z;
  62. std::cout << "foo_struct::operator() called with arguments: "
  63. << x << ", " << y << ", " << z
  64. << " result is : " << res
  65. << std::endl;
  66. return res;
  67. }
  68. };
  69.  
  70.  
  71. int main(void)
  72. {
  73. // typedefs
  74. using function_type = std::function<double(int, float, double)>;
  75.  
  76. // foo_struct instance
  77. foo_struct fs;
  78.  
  79. // here we will store all binded functions
  80. std::vector<function_type> bindings;
  81.  
  82. // var #1 - you can use simple function
  83. function_type var1 = foo_fn;
  84. bindings.push_back(var1);
  85.  
  86. // var #2 - you can use member function
  87. function_type var2 = std::bind(&foo_struct::foo_fn, fs, _1, _2, _3);
  88. bindings.push_back(var2);
  89.  
  90. // var #3 - you can use member function with different signature
  91. // foo_fn_4 has different count of arguments and types
  92. function_type var3 = std::bind(&foo_struct::foo_fn_4, fs, _1, _3, _2, 0l);
  93. bindings.push_back(var3);
  94.  
  95. // var #4 - you can use object with overloaded operator()
  96. function_type var4 = fs;
  97. bindings.push_back(var4);
  98.  
  99. // var #5 - you can use lambda function
  100. function_type var5 = [](int x, float y, double z)
  101. {
  102. double res = x + y + z;
  103. std::cout << "lambda called with arguments: "
  104. << x << ", " << y << ", " << z
  105. << " result is : " << res
  106. << std::endl;
  107. return res;
  108. };
  109. bindings.push_back(var5);
  110.  
  111. std::cout << "Test stored functions with arguments: x = 1, y = 2, z = 3"
  112. << std::endl;
  113.  
  114. for (auto f : bindings)
  115. f(1, 2, 3);
  116.  
  117. }
Success #stdin #stdout 0s 3476KB
stdin
Standard input is empty
stdout
Test stored functions with arguments: x = 1, y = 2, z = 3
foo_fn called with arguments: 1, 2, 3 result is : 6
foo_struct::foo_fn called with arguments: 1, 2, 3 result is : 6
foo_struct::foo_fn_4 called with arguments: 1, 3, 2, 0 result is : 6
foo_struct::operator() called with arguments: 1, 2, 3 result is : 6
lambda  called with arguments: 1, 2, 3 result is : 6