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

std::sort 排序时迭代器类型不匹配会崩溃
用 std::sort 最常见的崩法不是数据错,而是传了两个不同容器的迭代器——比如拿 vector 的 begin() 和 list 的 end() 混用。编译器通常不报错,但运行时触发断言或直接段错误。
- 确保两个迭代器来自同一容器、同一种类(
vector::iterator和vector::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::find 和 std::find_if 都返回迭代器,找不到就返回容器的 end()。新手常写成 if (it == nullptr),这在绝大多数编译器下编译不过;更隐蔽的是写成 if (!it),因为迭代器一般不支持隐式转 bool。
- 正确写法永远是
if (it != container.end()) - 对
std::string,std::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::copy或std::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,可能截断









