热门IT资讯网

C++0x-Lambda表达式

发表于:2024-11-28 作者:热门IT资讯网编辑
编辑最后更新 2024年11月28日,/** 注意:Lambdas表达式隐式定义并构建不具名函数对象*////////////////////////////////////////////////////////////////////
  1. /*
  2. * 注意:Lambdas表达式隐式定义并构建不具名函数对象
  3. */
  4. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  5. /*
  6. * []操作符为lambda引导符,(int n)为lambda参数声明
  7. * 不具名函数对象类的函数调用操作符默认返回void
  8. * {}说明函数体是复合语句
  9. * 由以下代码可以看出lambda表达式的效果和函数对象一样
  10. */
  11. // 实例代码1:
  12. #include
  13. #include
  14. #include
  15. using namespace std;
  16. struct LambdaFunctor {
  17. void operator() (int n) {
  18. cout << n << " ";
  19. }
  20. };
  21. int main() {
  22. vector <int> v;
  23. for (int i = 0; i < 10; ++i) {
  24. v.push_back(i);
  25. }
  26. for_each (v.begin(), v.end(), [] (int n) {
  27. cout << n << " ";
  28. });
  29. cout << endl;
  30. for_each (v.begin(), v.end(), LambdaFunctor());
  31. cout << endl;
  32. return 0;
  33. }
  34. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  35. /*
  36. * lambda表达式中若有{return expression;}
  37. * 则lambda的返回类型就会自动被推断成expression的类型
  38. * 但是过于复杂的声明语句lambda函数不会自动推断返回类型
  39. * 必须显示指定返回类型(实质是函数体中只有一个返回语句时可推断)
  40. *
  41. * 注意:-> type 指定返回值类型,必须置于()参数表后
  42. */
  43. // 实例代码2:
  44. #include
  45. #include
  46. #include
  47. using namespace std;
  48. template <typename func>
  49. void test(func a) {
  50. if (a(1, 0)) {
  51. cout << 1 << endl;
  52. } else {
  53. cout << 0 << endl;
  54. }
  55. }
  56. int main() {
  57. test([] (int a, int b) {
  58. return a > b;
  59. });
  60. return 0;
  61. }
  62. // 实例代码3:
  63. #include
  64. #include
  65. #include
  66. using namespace std;
  67. template <typename func>
  68. void test(func a) {
  69. cout << a(1, 0) << endl;
  70. }
  71. int main() {
  72. test([] (int a, int b) -> int {
  73. if (a % 2 == 0) {
  74. return a * a * a;
  75. } else {
  76. return a / 2;
  77. }
  78. });
  79. return 0;
  80. }
  81. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  82. /*
  83. * 通常空[]表示lambda是无状态的,即不包含数据成员
  84. * 在lambda引导符[]中可以指定capture-list
  85. * 函数对象和lambda效果一样,函数对象存储了局部变量的拷贝
  86. * 所以本质上"按值"传递对lambda而言就是隐式创建韩局部变量函数对象
  87. * 注意点:
  88. * (a)在lambda中不能修改通过传递获得的拷贝,默认情况下函数调用操作符是const属性
  89. * (b)有些对象拷贝开销大
  90. * (c)局部变量的更新不会反应到通过传递获得的拷贝
  91. */
  92. // 实例代码4:
  93. #include
  94. #include
  95. #include
  96. using namespace std;
  97. // 创建含局部变量的函数对象
  98. struct LambdaFunctor {
  99. LambdaFunctor(int a, int b) : m_a(a), m_b(b) {}
  100. bool operator() () const {
  101. if (m_a % 2 == 0) {
  102. return m_a * m_a * m_a;
  103. } else {
  104. return m_a / 2;
  105. }
  106. }
  107. private:
  108. int m_a, m_b;
  109. };
  110. template <typename func>
  111. void test(func a) {
  112. cout << a() << endl;
  113. }
  114. int main() {
  115. int a = 1, b = 0;
  116. test([a, b] () -> int {
  117. if (a % 2 == 0) {
  118. return a * a * a;
  119. } else {
  120. return a / 2;
  121. }
  122. });
  123. test(LambdaFunctor(a, b));
  124. return 0;
  125. }
  126. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  127. /*
  128. * 也可以利用[=]形式lambda引导符"按值传递任何东西"
  129. * 利用mutable将函数调用操作符转为non-const属性
  130. */
  131. // 实例代码5:
  132. #include
  133. #include
  134. #include
  135. using namespace std;
  136. template <typename func>
  137. void test(func a) {
  138. cout << a() << endl;
  139. }
  140. int main() {
  141. int a = 1, b = 0;
  142. test([=] () mutable -> int {
  143. if (a % 2 == 0) {
  144. a = 2;
  145. return a * a * a;
  146. } else {
  147. a = 4;
  148. return a / 2;
  149. }
  150. });
  151. return 0;
  152. }
  153. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  154. /*
  155. * 为了避免拷贝的开销出现通过引用传递
  156. * 语法形式[&x, &y],隐式构建局部变量为引用变量
  157. * 也可以用[&]来表示"按引用传递任何东西"
  158. * 可以不用mutable改变属性
  159. * 可以在引导符[]进行混合使用传递,例如:[&,x,y],[x,&a,y,&b]
  160. */
  161. // 实例代码6:
  162. #include
  163. #include
  164. #include
  165. using namespace std;
  166. template <typename func>
  167. void test(func a) {
  168. cout << a() << endl;
  169. }
  170. int main() {
  171. int a = 1;
  172. test([&a] () -> int {
  173. if (a % 2 == 0) {
  174. a = 2;
  175. return a * a * a;
  176. } else {
  177. a = 4;
  178. return a / 2;
  179. }
  180. });
  181. cout << a << endl;
  182. return 0;
  183. }
  184. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  185. /*
  186. * 注意有一种特别传参用法this
  187. * 但无法获得一个lambda对象他自身的this指针
  188. * [=],[&]可以隐式传递this,[&this]不可以使用
  189. */
  190. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  191. /*
  192. * 当lambda不带参数时可以不加()但是同样也不能显示指定返回值类型
  193. * 但是可以隐式推断返回值类型
  194. * 定义lambda表达式后可以立即用()操作符使用表达式
  195. * 可以用#define来简化定义一个lambda表达式
  196. * 但是不可以用typedef来定义一个类型
  197. */
  198. // 实例代码7:
  199. #include
  200. #include
  201. #include
  202. using namespace std;
  203. template <typename func>
  204. void test(func a) {
  205. cout << a() << endl;
  206. }
  207. int main() {
  208. int a = 1;
  209. test([] {
  210. return 9;
  211. });
  212. return 0;
  213. }
  214. // 实例代码8:
  215. #include
  216. #include
  217. #include
  218. using namespace std;
  219. template <typename func>
  220. void test(func a) {
  221. cout << a() << endl;
  222. }
  223. #define mengxm [] () { cout << "mengxm" << endl; }
  224. int main() {
  225. mengxm();
  226. return 0;
  227. }
0