c++中如何使用algorithm头文件_c++常用算法函数总结【必备】

5次阅读

std::sort崩溃主因是混用不同容器或类型迭代器,须确保同源同类型;find系列返回end()而非nullptr;transform禁重叠范围;accumulate需自定义类型支持operator+或显式传操作函数。

c++中如何使用algorithm头文件_c++常用算法函数总结【必备】

std::sort 排序时迭代器类型不匹配会崩溃

std::sort 最常见的崩法不是数据错,而是传了两个不同容器的迭代器——比如拿 vectorbegin()listend() 混用。编译器通常不报错,但运行时触发断言或直接段错误。

  • 确保两个迭代器来自同一容器、同一种类(vector::iteratorvector::const_iterator 也不能混,除非用 std::sort 的 const 版本)
  • std::Array 或原生数组,用 &arr[0]&arr[N],别用 std::begin(arr)std::end(arr) 混搭指针
  • 自定义比较函数里别修改被比较对象的状态,否则 std::sort 可能无限循环或崩溃

find / find_if 找不到时返回 end(),不是 nullptr

std::findstd::find_if 都返回迭代器,找不到就返回容器的 end()。新手常写成 if (it == nullptr),这在绝大多数编译器下编译不过;更隐蔽的是写成 if (!it),因为迭代器一般不支持隐式转 bool

  • 正确写法永远是 if (it != container.end())
  • std::Stringstd::string::find 返回 std::string::npos(值为 -1),和 algorithm 里的 find 不是一套逻辑,别混淆
  • 如果容器是 const 的,find 返回 const_iterator,不能直接赋给非 const 迭代器变量

transform 输入输出范围重叠时必须用 std::copy 或小心偏移

当用 std::transform 把一个容器的内容“原地”变换(比如全转大写),输入迭代器和输出迭代器指向同一块内存,但起始位置不同——这时标准行为是未定义的。常见于把 vec.begin()vec.end() 映射到 vec.begin() + 1 这种场景。

  • 安全做法:输出范围不能和输入范围有重叠,除非你明确知道该算法支持(std::transform 不支持)
  • 真要原地变,先用 std::for_each 或手写循环;想平移数据,用 std::copystd::move
  • 注意 std::copy 的目标范围必须足够大,否则越界——它不会自动扩容

accumulate 默认加法依赖 T 的 operator+,自定义类型容易漏定义

std::accumulate 默认用 + 累加,模板参数 T 必须支持 T operator+(const T&, const T&)。比如你写了个 Struct Vec2 { Float x, y; };,不重载 operator+ 就直接用 accumulate,编译失败信息往往很长且指向内部实现,很难定位。

立即学习C++免费学习笔记(深入)”;

  • 最简修复:给自定义类型加 friend Vec2 operator+(Vec2 a, Vec2 b) { return {a.x+b.x, a.y+b.y}; }
  • 如果只是临时用,传第三个参数指定初始值(如 Vec2{0,0})并显式传二元操作函数,绕过默认加法
  • 注意 accumulate 第三个参数类型决定返回类型,和容器元素类型无关;若传 int 但容器是 long long,可能截断

事情说清了就结束。algorithm 头文件本身不管理内存、不检查边界、不区分 const 正确性——这些都得你自己盯住。

text=ZqhQzanResources