泛型算法

可以支持多种类型的算法

  1. #include <iostream>
  2. #include <vector>
  3. int main()
  4. {
  5. std::vector<int> vec{1,7,5,3,2};
  6. std::sort(std::begin(vec),std::end(vec));
  7. }

引入泛型算法而不是方法的形式

  • 内建数据类型不支持方法
  • 计算逻辑存在相似性,避免重复

泛型算法通常来说不复杂,但优化效果足够好
一些泛型算法与方法同名,实现功能类似,一般优先使用方法
例如:std::find VS std::map::find

泛型算法的分类
读算法:给定一个迭代区间,读取其中的元素并进行计算

  • accumulate /find/count

写算法:向一个迭代区间写入元素

  • 单纯写操作:fill/fill_n
  • 读+写操作:transform/copy
  • 写操作要注意写入目标区间足够大,不然会造成内存越界

排序算法:

  • sort/unique
  • 泛型算法使用迭代器实现元素访问
  • 迭代器的分类:

    1. - 输入迭代器<br /> - 输出迭代器<br /> - 前向迭代器<br /> - 双向迭代器<br /> - 随机访问迭代器
  • 一些算法会根据迭代器类别的不同引入相应的优化:例如distance 算法

Lambda 表达式
捕获
针对函数体中使用的局部自动对象进行捕获

  1. #include <iostream>
  2. int main()
  3. {
  4. int y = 10;// 这里如果改为static int y = 10; 编译错误
  5. auto x = [y] (int val) {return val > y;}; // 捕获
  6. std::cout << x(2) << std::endl;
  7. }

值捕获、引用捕获以及混合捕获

  1. #include <iostream>
  2. int main()
  3. {
  4. int y = 10;
  5. int z = 3;
  6. auto x = [&y,z] (int val) {++y;return val > z;}; // 捕获 [=] 值捕获 [&] 引用捕获
  7. std::cout << x(5) << std::endl;
  8. std::cout << y << std::endl;
  9. }

this捕获

  1. #include <iostream>
  2. struct Str
  3. {
  4. auto fun()
  5. {
  6. int val = 3;
  7. auto lam = [val,this] ()
  8. {
  9. return val > x;
  10. };
  11. }
  12. int x;
  13. };
  14. int main()
  15. {
  16. Str s{};
  17. s.fun();
  18. }

初始化捕获(C++14)

  1. int main()
  2. {
  3. int x = 3;
  4. auto lam = [y = x] (int val)
  5. {
  6. return val > y;
  7. };
  8. std::cout << lam(100) << std::endl;
  9. }

特殊:

  1. int main()
  2. {
  3. int x = 3;
  4. auto lam = [x = x] (int val)
  5. {
  6. return val > x;//右边的x
  7. };
  8. std::cout << lam(100) << std::endl;
  9. }

this捕获(C++17)
解决this指针不安全的问题
*说明符(mutable / constexpr (C++17) / consteval (C++20)……)

  1. #include <iostream>
  2. int main()
  3. {
  4. int y = 10;
  5. auto lam = [y] (int val)mutable
  6. {
  7. ++y;
  8. return val > y;
  9. };
  10. std::cout << lam(33) << std::endl;
  11. }

模板形参 (C++20)

  1. #include <iostream>
  2. int main()
  3. {
  4. auto lam = [] <typename T> (T val) consteval
  5. {
  6. return val + 1;
  7. };
  8. constexpr int val = lam(100);
  9. std::cout << val << std::endl;
  10. }

lambda表达式的深入应用

  • 捕获时计算(C++14 ) ```cpp

    include

int main() { int x = 3; int y = 5; auto lam = [z = x + y] () { return z; }; std::cout << lam() << std::endl; }

  1. - 即调用函数表达式(Immediately-Invoked Function Expression, IIFE
  2. ```cpp
  3. #include <iostream>
  4. int main()
  5. {
  6. int x = 3;
  7. int y = 5;
  8. const auto val = [z = x + y] ()
  9. {
  10. return z;
  11. }();
  12. std::cout << val << std::endl;
  13. }
  • 使用auto 避免复制(C++14 )
  • Lifting (C++14 ) ```cpp

    include

auto fun(int val) { return val + 10; }

auto fun(double val) { return val + 1; }

int main() { auto lam = [] (auto x) { return fun(x); }; std::cout << lam(3) << std::endl; std::cout << lam(3.5) << std::endl; }

  1. - 递归调用(C++14
  2. ```cpp
  3. #include <iostream>
  4. int main()
  5. {
  6. auto factorial = [] (int n)
  7. {
  8. auto f_impl = [] (int n ,const auto& impl) -> int
  9. {
  10. return n > 1 ? n * impl(n - 1,impl) : 1;
  11. };
  12. return f_impl(n, f_impl);
  13. };
  14. std::cout << factorial(5) << std::endl;
  15. }