std::sort仅支持随机访问迭代器,不可用于std::list或std::forward_list;应改用成员函数sort()或拷贝至vector排序;比较函数须const、noexcept且无副作用;需稳定性时用std::stable_sort。

sort 函数必须传入随机访问迭代器
你不能对 std::list 或 std::forward_list 直接用 std::sort,它只接受支持 operator+ 和指针算术的迭代器(比如 std::vector、std::deque、原生数组)。传入 list.begin() 会编译失败,错误信息类似:no match for 'operator-'...
- 正确做法:对
std::vector<int>用std::sort(v.begin(), v.end()) - 对
std::list改用lst.sort()(成员函数,非标准算法) - 若坚持用算法,先拷贝到
vector,排序后再赋回(仅当数据量小且不敏感时)
自定义比较函数要注意 const 和 noexcept
写 lambda 或函数对象时,如果捕获了局部变量或调用了可能抛异常的函数,std::sort 在某些标准库实现(如 libstdc++)中可能崩溃或行为未定义——因为内部实现假设比较函数是 noexcept 且不修改状态。
- 安全写法:
[&](const auto& a, const auto& b) { return a.key < b.key; }(显式 const 引用 + 无捕获副作用) - 避免:
[x](auto a, auto b) { return a + x < b; }(值传递、带捕获、未声明 noexcept) - 结构体排序常用:
std::sort(v.begin(), v.end(), [](const Person& a, const Person& b) { return a.age < b.age; });
sort 不稳定,相同元素相对顺序可能变
如果你依赖“相等元素保持原有先后顺序”,std::sort 不满足。例如按姓名排序学生列表,同名者原本按学号升序,排序后学号顺序可能被打乱。
- 改用
std::stable_sort:语义完全一致,只是保证稳定性,性能略低(通常多一次内存分配) -
std::sort平均复杂度 O(n log n),最坏也是 O(n log n)(C++11 起强制要求),但stable_sort最坏可能是 O(n log² n) - 小数据量(stable_sort 实际耗时
原生数组排序要小心迭代器边界
对 C 风格数组用 std::sort,常见错误是把数组名当首地址却忘了算长度,或者误用 sizeof(arr)/sizeof(*arr) 在函数参数里(此时 arr 已退化为指针)。
立即学习“C++免费学习笔记(深入)”;
- 正确:
int arr[] = {3,1,4}; std::sort(arr, arr + 3); - 错误:
void f(int a[]) { std::sort(a, a + sizeof(a)); }—— 这里sizeof(a)是指针大小(8),不是数组长度 - 更安全:用
std::array或std::vector替代原生数组,避免这类低级错误
operator- 和 noexcept 关键字,基本就能定位。











