C++ STL 常用算法详解

C++ STL 常用算法详解

引言

C++标准模板库(STL)提供了一套强大的通用算法,这些算法独立于具体的容器,通过迭代器与容器交互。熟练掌握这些算法可以大大提高代码的简洁性、可读性和开发效率。本文旨在整理最常用的STL算法,作为日常开发的快速参考手册。

C++20 重要更新

  • 引入范围库(Ranges),提供新的算法重载(位于 std::ranges 命名空间),支持直接操作范围(如 rng)而非迭代器对,并支持投影(projection)功能。
  • 新增算法:shift_leftshift_right
  • 许多现有算法在 C++20 中成为 constexpr,允许在编译时计算。

包含头文件

大多数通用算法定义在 <algorithm> 头文件中,部分数值算法在 <numeric> 中,还有一些涉及函数对象的在 <functional> 中。C++20 范围算法也在 <algorithm> 中(通过 std::ranges 命名空间提供),范围视图(views)则在 <ranges> 头文件中。

1
2
3
4
5
#include <algorithm>
#include <numeric>
#include <functional>
// C++20 范围视图需要
#include <ranges>

算法分类

  • 非修改式序列操作:不改变容器内容,如查找、计数等。
  • 修改式序列操作:会修改容器元素(但不改变容器大小),如复制、替换、变换等。
  • 排序和相关操作:排序、二分查找、集合操作等。
  • 数值算法:求和、内积、部分和等。
  • C++20 新特性:范围算法、shift_left/rightconstexpr 支持。

非修改式序列操作

for_each

  • 功能:对序列中的每个元素应用指定函数。
  • 原型for_each(InputIt first, InputIt last, UnaryFunction f)
  • 返回值:返回 f(在C++11后返回移动构造后的 f)。
  • C++20:新增 std::ranges::for_each 范围版本,并支持投影。另外 for_each_n(C++17 已引入)在 C++20 中也有范围版本。
  • 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <vector>
#include <algorithm>

void print(int n) { std::cout << n << ' '; }

int main() {
std::vector<int> v = {1, 2, 3, 4};
std::for_each(v.begin(), v.end(), print); // 输出:1 2 3 4
std::for_each(v.begin(), v.end(), [](int &n){ n++; }); // 使用lambda修改元素
// v 变为 {2,3,4,5}

// C++20 范围版本
std::ranges::for_each(v, print); // 更简洁
}

find / find_if

  • 功能:在范围内查找第一个等于某值(或满足谓词)的元素。
  • 原型
    • find(InputIt first, InputIt last, const T& value)
    • find_if(InputIt first, InputIt last, UnaryPredicate p)
  • 返回值:指向第一个匹配元素的迭代器,若未找到则返回 last
  • C++20std::ranges::find, std::ranges::find_if 支持范围和投影。
  • 示例
1
2
3
4
5
6
7
std::vector<int> v = {1,2,3,4,5};
auto it = std::find(v.begin(), v.end(), 3); // it 指向 3
auto it2 = std::find_if(v.begin(), v.end(), [](int x){ return x > 3; }); // it2 指向 4

// C++20 范围版本
auto it3 = std::ranges::find(v, 3);
auto it4 = std::ranges::find_if(v, [](int x){ return x > 3; });

count / count_if

  • 功能:返回范围内等于某值(或满足谓词)的元素个数。
  • 原型
    • count(InputIt first, InputIt last, const T& value)
    • count_if(InputIt first, InputIt last, UnaryPredicate p)
  • 返回值:满足条件的元素数量(difference_type)。
  • C++20std::ranges::count, std::ranges::count_if
  • 示例
1
2
3
4
5
6
std::vector<int> v = {1,2,3,4,3,2,1};
int cnt = std::count(v.begin(), v.end(), 3); // cnt = 2
int cnt_if = std::count_if(v.begin(), v.end(), [](int x){ return x % 2 == 0; }); // 偶数个数:3

// C++20 范围版本
auto cnt2 = std::ranges::count(v, 3);
  • 功能:在范围 [first1, last1) 中查找第一个子序列 [first2, last2) 出现的位置。
  • 原型search(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2, ForwardIt2 last2)
  • 返回值:指向子序列起始位置的迭代器,若未找到则返回 last1
  • C++20std::ranges::search
  • 示例
1
2
3
4
5
6
std::vector<int> v = {1,2,3,4,5,3,4,6};
std::vector<int> sub = {3,4};
auto it = std::search(v.begin(), v.end(), sub.begin(), sub.end()); // it 指向第一个 3

// C++20 范围版本
auto it2 = std::ranges::search(v, sub).begin(); // 返回子范围,需要 .begin()

equal

  • 功能:比较两个序列是否相等(元素一一对应相同)。
  • 原型equal(InputIt1 first1, InputIt1 last1, InputIt2 first2)(假设第二个序列长度至少与第一个相等)
  • 返回值:若两个范围相等返回 true,否则 false
  • C++20std::ranges::equal 支持范围和投影,并且可指定结束迭代器。
  • 示例
1
2
3
4
5
6
std::vector<int> a = {1,2,3};
std::vector<int> b = {1,2,3};
bool eq = std::equal(a.begin(), a.end(), b.begin()); // true

// C++20 范围版本(更安全,同时比较两个范围)
bool eq2 = std::ranges::equal(a, b);

修改式序列操作

copy / copy_if

  • 功能:将范围 [first, last) 中的元素复制到从 d_first 开始的另一范围。
  • 原型
    • copy(InputIt first, InputIt last, OutputIt d_first)
    • copy_if(InputIt first, InputIt last, OutputIt d_first, UnaryPredicate pred) (C++11)
  • 返回值:指向目标范围最后被复制元素的下一个位置的迭代器。
  • C++20std::ranges::copy, std::ranges::copy_if,返回更详细的结果对象(包含输入迭代器和输出迭代器)。
  • 示例
1
2
3
4
5
6
7
8
9
std::vector<int> src = {1,2,3,4,5};
std::vector<int> dest(src.size());
std::copy(src.begin(), src.end(), dest.begin()); // dest = {1,2,3,4,5}

std::vector<int> even;
std::copy_if(src.begin(), src.end(), std::back_inserter(even), [](int x){ return x%2==0; }); // even = {2,4}

// C++20 范围版本
auto result = std::ranges::copy(src, dest.begin()); // result.in 指向 src.end(), result.out 指向 dest.end()

fill

  • 功能:将指定值赋给范围 [first, last) 中的每个元素。
  • 原型fill(ForwardIt first, ForwardIt last, const T& value)
  • 返回值:无(void)。
  • C++20std::ranges::fill
  • 示例
1
2
3
4
std::vector<int> v(5);
std::fill(v.begin(), v.end(), 42); // v = {42,42,42,42,42}
// C++20
std::ranges::fill(v, 42);

transform

  • 功能:对序列中的每个元素应用函数,并将结果写入目标范围(可原地修改)。
  • 原型
    • 一元形式:transform(InputIt first1, InputIt last1, OutputIt d_first, UnaryOperation unary_op)
    • 二元形式:transform(InputIt1 first1, InputIt1 last1, InputIt2 first2, OutputIt d_first, BinaryOperation binary_op)
  • 返回值:指向目标范围最后元素的下一个位置的迭代器。
  • C++20std::ranges::transform,支持范围和投影,返回包含输入和输出迭代器的结果对象。
  • 示例
1
2
3
4
5
6
7
8
9
10
11
12
std::vector<int> in = {1,2,3};
std::vector<int> out(in.size());
std::transform(in.begin(), in.end(), out.begin(), [](int x){ return x*x; }); // out = {1,4,9}

// C++20 范围版本
std::ranges::transform(in, out.begin(), [](int x){ return x*x; });

// 二元形式
std::vector<int> a = {1,2,3}, b = {4,5,6}, c(3);
std::transform(a.begin(), a.end(), b.begin(), c.begin(), std::plus<int>()); // c = {5,7,9}
// C++20 范围二元版本
std::ranges::transform(a, b, c.begin(), std::plus<int>());

replace / replace_if

  • 功能:将范围内等于某值(或满足谓词)的元素替换为新值。
  • 原型
    • replace(ForwardIt first, ForwardIt last, const T& old_value, const T& new_value)
    • replace_if(ForwardIt first, ForwardIt last, UnaryPredicate p, const T& new_value)
  • 返回值:void。
  • C++20std::ranges::replace, std::ranges::replace_if
  • 示例
1
2
3
4
std::vector<int> v = {1,2,3,2,1};
std::replace(v.begin(), v.end(), 2, 99); // v = {1,99,3,99,1}
// C++20
std::ranges::replace(v, 2, 99);

remove / remove_if

  • 功能:从范围中移除等于某值(或满足谓词)的元素,但不会改变容器大小,它只是将“保留”的元素移动到前面,返回指向新逻辑结尾的迭代器。
  • 原型
    • remove(ForwardIt first, ForwardIt last, const T& value)
    • remove_if(ForwardIt first, ForwardIt last, UnaryPredicate p)
  • 返回值:指向新范围末尾的迭代器。
  • 注意:通常配合容器的 erase 成员函数一起使用(称为 erase-remove 惯用法)。
  • C++20std::ranges::remove, std::ranges::remove_if
  • 示例
1
2
3
4
5
6
7
std::vector<int> v = {1,2,3,2,1};
auto new_end = std::remove(v.begin(), v.end(), 2);
v.erase(new_end, v.end()); // v = {1,3,1}

// C++20 范围版本
auto result = std::ranges::remove(v, 2);
v.erase(result.begin(), result.end());

reverse

  • 功能:反转范围内元素的顺序。
  • 原型reverse(BidirectionalIt first, BidirectionalIt last)
  • 返回值:void。
  • C++20std::ranges::reverse
  • 示例
1
2
3
4
std::vector<int> v = {1,2,3,4};
std::reverse(v.begin(), v.end()); // v = {4,3,2,1}
// C++20
std::ranges::reverse(v);

rotate

  • 功能:将范围向左旋转,使得 middle 指向的元素成为新范围的第一个元素。
  • 原型rotate(ForwardIt first, ForwardIt middle, ForwardIt last)
  • 返回值:指向原来第一个元素所在新位置的迭代器(C++11后)。
  • C++20std::ranges::rotate
  • 示例
1
2
3
4
std::vector<int> v = {1,2,3,4,5};
std::rotate(v.begin(), v.begin()+2, v.end()); // v = {3,4,5,1,2}
// C++20
std::ranges::rotate(v, v.begin()+2);

unique

  • 功能:移除范围内连续的重复元素(只保留第一个)。通常用于排序后的序列。
  • 原型unique(ForwardIt first, ForwardIt last),也可以带自定义比较谓词。
  • 返回值:指向新范围末尾的迭代器。
  • 注意:不会改变容器大小,需要配合 erase 使用。
  • C++20std::ranges::unique
  • 示例
1
2
3
4
5
6
7
std::vector<int> v = {1,1,2,2,3,4,4,5};
auto last = std::unique(v.begin(), v.end());
v.erase(last, v.end()); // v = {1,2,3,4,5}

// C++20
auto result = std::ranges::unique(v);
v.erase(result.begin(), result.end());

C++20 新算法:shift_left / shift_right

  • 功能:将范围内的元素向左或向右移动 n 个位置。移动后,空出的位置元素变为可移动后的状态(通常被移动后的对象处于有效但未指定的状态)。对于 shift_left,范围的前 n 个元素被移除;对于 shift_right,范围的后 n 个元素被移除。
  • 原型
    • shift_left(ForwardIt first, ForwardIt last, typename std::iterator_traits<ForwardIt>::difference_type n)
    • shift_right(ForwardIt first, ForwardIt last, typename std::iterator_traits<ForwardIt>::difference_type n)
  • 返回值:返回新的范围末尾的迭代器(对于 shift_left,返回 last - n;对于 shift_right,返回 first + n)。注意,这个算法不会改变容器大小,只是移动元素。
  • 注意:要求 n >= 0。如果 n >= last-first,则行为未定义(但某些实现可能返回 first/last)。
  • C++20std::shift_left, std::shift_right
  • 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <algorithm>
#include <vector>
#include <iostream>

int main() {
std::vector<int> v = {1,2,3,4,5};
// 向左移动 2 个位置
auto new_end = std::shift_left(v.begin(), v.end(), 2);
v.erase(new_end, v.end()); // v 变为 {3,4,5}
// 此时 v = {3,4,5}

v = {1,2,3,4,5};
// 向右移动 2 个位置
auto new_begin = std::shift_right(v.begin(), v.end(), 2);
// 前两个位置(0和1)现在是未指定状态,通常是被移动后的元素
// 为了安全,可以覆盖它们
std::fill(v.begin(), new_begin, 0); // 填充被移动出的位置
// v 可能为 {0,0,1,2,3}(取决于实现)
}

排序和相关操作

sort

  • 功能:对范围 [first, last) 进行升序排序(默认使用 operator<)。
  • 原型sort(RandomIt first, RandomIt last)sort(RandomIt first, RandomIt last, Compare comp)
  • 复杂度:平均 O(N log N)。
  • C++20std::ranges::sort,支持投影。
  • 示例
1
2
3
4
5
6
7
8
9
10
std::vector<int> v = {4,2,5,1,3};
std::sort(v.begin(), v.end()); // v = {1,2,3,4,5}
std::sort(v.begin(), v.end(), std::greater<int>()); // v = {5,4,3,2,1}

// C++20 范围版本
std::ranges::sort(v);
// 使用投影对自定义对象排序
struct Person { std::string name; int age; };
std::vector<Person> people = {{"Alice",30}, {"Bob",25}};
std::ranges::sort(people, {}, &Person::age); // 按 age 排序(第三个参数是投影)

stable_sort

  • 功能:稳定排序,保持相等元素的相对顺序。
  • 原型:同 sort
  • C++20std::ranges::stable_sort

partial_sort

  • 功能:重排范围,使得 [first, middle) 包含整个范围中最小的 middle-first 个元素并已排序,其余元素置于 [middle, last) 中(顺序未指定)。
  • 原型partial_sort(RandomIt first, RandomIt middle, RandomIt last, Compare comp = <)
  • C++20std::ranges::partial_sort

nth_element

  • 功能:重排范围,使得第 nth 位置的元素就是整个范围排序后应处于该位置的元素,且所有在它之前的元素都不大于它,之后的元素都不小于它。
  • 原型nth_element(RandomIt first, RandomIt nth, RandomIt last, Compare comp = <)
  • C++20std::ranges::nth_element
  • 功能:在已排序范围内检查是否存在等于某值的元素。
  • 原型binary_search(ForwardIt first, ForwardIt last, const T& value),也可带比较函数。
  • 返回值:bool。
  • C++20std::ranges::binary_search
  • 示例
1
2
3
4
std::vector<int> v = {1,2,3,4,5};
bool found = std::binary_search(v.begin(), v.end(), 3); // true
// C++20
bool found2 = std::ranges::binary_search(v, 3);

lower_bound / upper_bound

  • 功能:在已排序范围内查找第一个不小于lower_bound)或大于upper_bound)给定值的元素位置。
  • 原型lower_bound(ForwardIt first, ForwardIt last, const T& value)
  • 返回值:迭代器。
  • C++20std::ranges::lower_bound, std::ranges::upper_bound
  • 示例
1
2
3
4
5
6
7
std::vector<int> v = {1,2,2,2,3,4};
auto low = std::lower_bound(v.begin(), v.end(), 2); // 指向第一个2
auto up = std::upper_bound(v.begin(), v.end(), 2); // 指向3
// 区间 [low, up) 包含所有值为2的元素

// C++20
auto low2 = std::ranges::lower_bound(v, 2);

merge

  • 功能:合并两个已排序范围到目标范围(结果也是有序的)。
  • 原型merge(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt d_first)
  • 返回值:指向目标范围末尾的迭代器。
  • C++20std::ranges::merge
  • 示例
1
2
3
4
std::vector<int> a = {1,3,5}, b = {2,4,6}, c(6);
std::merge(a.begin(), a.end(), b.begin(), b.end(), c.begin()); // c = {1,2,3,4,5,6}
// C++20
std::ranges::merge(a, b, c.begin());

includes

  • 功能:检查已排序范围 [first1, last1) 是否包含另一个已排序范围 [first2, last2) 中的所有元素。
  • 原型includes(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2)
  • 返回值:bool。
  • C++20std::ranges::includes
  • 示例
1
2
3
4
std::vector<int> a = {1,2,3,4,5}, b = {2,4};
bool in = std::includes(a.begin(), a.end(), b.begin(), b.end()); // true
// C++20
bool in2 = std::ranges::includes(a, b);

set_union / set_intersection

  • 功能:对两个已排序范围执行集合操作(并集、交集等),结果写入目标范围。
  • 原型
    • set_union(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt d_first)
    • set_intersection(...)
  • 返回值:指向目标范围末尾的迭代器。
  • C++20std::ranges::set_union, std::ranges::set_intersection 等。
  • 示例
1
2
3
4
5
6
std::vector<int> a = {1,2,3,4}, b = {3,4,5,6}, u, i;
std::set_union(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(u)); // u = {1,2,3,4,5,6}
std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(i)); // i = {3,4}

// C++20
std::ranges::set_union(a, b, std::back_inserter(u));

min / max

  • 功能:返回两个值中的较小/较大者。
  • 原型min(const T& a, const T& b),也可接受比较函数。
  • 返回值:const T&(通常返回引用)。
  • C++20:新增 std::ranges::min, std::ranges::max,可接受初始化列表和投影。此外,std::ranges::minmax 返回一对。
  • 示例
1
2
3
int m = std::min(3, 5); // 3
// C++20 范围版本支持投影
std::ranges::min({3,1,4}); // 1

min_element / max_element

  • 功能:返回范围中的最小/最大元素的迭代器。
  • 原型min_element(ForwardIt first, ForwardIt last),也可带比较函数。
  • 返回值:迭代器。
  • C++20std::ranges::min_element, std::ranges::max_element
  • 示例
1
2
3
4
std::vector<int> v = {3,1,4,1,5};
auto it = std::min_element(v.begin(), v.end()); // 指向第一个1
// C++20
auto it2 = std::ranges::min_element(v);

数值算法

accumulate

  • 功能:对范围元素进行累加(或给定二元操作)。
  • 原型
    • accumulate(InputIt first, InputIt last, T init) (默认加法)
    • accumulate(InputIt first, InputIt last, T init, BinaryOperation op)
  • 返回值:累加结果。
  • C++20:无直接范围版本,但可使用 std::ranges::fold_left(C++23 才有),或结合范围视图使用 std::accumulatestd::ranges::begin/end
  • 示例
1
2
3
std::vector<int> v = {1,2,3,4};
int sum = std::accumulate(v.begin(), v.end(), 0); // 10
int product = std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>()); // 24

inner_product

  • 功能:计算两个序列的内积(对应元素相乘再累加),或类似操作。
  • 原型
    • inner_product(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init)
    • 也可指定加法和乘法运算。
  • C++20std::ranges::inner_product 尚未引入(C++23 有 fold 变种),但可用范围版本循环。
  • 示例
1
2
std::vector<int> a = {1,2,3}, b = {4,5,6};
int dot = std::inner_product(a.begin(), a.end(), b.begin(), 0); // 1*4 + 2*5 + 3*6 = 32

partial_sum

  • 功能:计算范围的部分和,并写入目标范围。
  • 原型partial_sum(InputIt first, InputIt last, OutputIt d_first),也可指定二元操作。
  • 返回值:指向目标范围末尾的迭代器。
  • C++20std::ranges::partial_sum(可能作为范围算法存在?实际上 C++20 未包含,但 C++23 会包含。可手动使用迭代器版本。)
  • 示例
1
2
std::vector<int> v = {1,2,3,4}, ps(v.size());
std::partial_sum(v.begin(), v.end(), ps.begin()); // ps = {1,3,6,10}

adjacent_difference

  • 功能:计算范围内相邻元素的差值,并写入目标范围。
  • 原型adjacent_difference(InputIt first, InputIt last, OutputIt d_first),也可指定二元操作。
  • C++20std::ranges::adjacent_difference 也未在 C++20 中,需用迭代器版本。
  • 示例
1
2
std::vector<int> v = {1,3,6,10}, diff(v.size());
std::adjacent_difference(v.begin(), v.end(), diff.begin()); // diff = {1,2,3,4}

其他常用算法

swap

  • 功能:交换两个对象的值。
  • 原型swap(T& a, T& b)(定义在 <utility> 中,但算法库也包含)。
  • C++20std::ranges::swap 是 CPO(定制点对象),但通常使用 std::swap 即可。
  • 示例
1
2
int a=1, b=2;
std::swap(a, b); // a=2, b=1

iter_swap

  • 功能:交换两个迭代器指向的元素。
  • 原型iter_swap(ForwardIt1 a, ForwardIt2 b)
  • C++20std::ranges::iter_swap 也是 CPO。
  • 示例
1
2
std::vector<int> v = {1,2};
std::iter_swap(v.begin(), v.begin()+1); // v = {2,1}

generate

  • 功能:通过反复调用函数对象生成值,填充范围。
  • 原型generate(ForwardIt first, ForwardIt last, Generator g)
  • C++20std::ranges::generate
  • 示例
1
2
3
4
5
std::vector<int> v(5);
int n = 0;
std::generate(v.begin(), v.end(), [&n]{ return n++; }); // v = {0,1,2,3,4}
// C++20
std::ranges::generate(v, [&n]{ return n++; });

C++20 新特性详述

1. 范围库(Ranges)

C++20 引入了范围库,提供了一组新的算法重载(位于 std::ranges 命名空间),它们:

  • 接受范围对象(如容器、视图)作为参数,而不必传递两个迭代器。
  • 支持投影(projection),可以在比较或操作之前对元素进行变换。
  • 返回更丰富的结果类型(例如 ranges::copy 返回包含输入和输出迭代器的结构)。
  • 与范围适配器(views)无缝协作,实现惰性求值和组合。

示例:使用范围算法和投影

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <algorithm>
#include <vector>
#include <iostream>

struct Person {
std::string name;
int age;
};

int main() {
std::vector<Person> people = {{"Alice", 30}, {"Bob", 25}, {"Charlie", 35}};

// 按年龄排序,使用投影
std::ranges::sort(people, {}, &Person::age);

// 打印名字(使用 for_each 和投影)
std::ranges::for_each(people, [](const std::string& name) {
std::cout << name << ' ';
}, &Person::name); // 投影到 name
// 输出:Bob Alice Charlie

// 结合范围视图:筛选年龄大于30的人
auto over30 = people | std::views::filter([](const Person& p) { return p.age > 30; })
| std::views::transform(&Person::name);
for (const auto& name : over30) {
std::cout << name << ' '; // 输出:Charlie
}
}

2. 新算法:shift_left / shift_right

已在“修改式序列操作”中介绍。

3. constexpr 支持

C++20 将许多算法标记为 constexpr,允许在编译时执行这些算法。例如:

1
2
3
4
5
6
7
8
9
constexpr int square(int x) { return x * x; }

constexpr std::array<int, 4> arr = {1,2,3,4};
constexpr auto squared = []{
std::array<int, 4> result{};
std::transform(arr.begin(), arr.end(), result.begin(), square);
return result;
}();
// squared 在编译时计算得到 {1,4,9,16}

注意:并非所有算法都可在编译时使用(例如需要动态内存的算法如 sort 通常不是 constexpr,但部分如 transformcopy 等可以)。

4. 范围适配器(Views)

虽然不是算法,但范围适配器常与算法一起使用。常用视图:

  • std::views::filter(pred):筛选满足谓词的元素。
  • std::views::transform(f):对每个元素应用函数。
  • std::views::take(n):取前 n 个元素。
  • std::views::drop(n):跳过前 n 个元素。
  • std::views::reverse:反转视图。
  • std::views::keys / values:用于 pair/tuple 容器(如 map)。

这些视图支持惰性求值,可与范围算法组合。


注意事项

  1. 迭代器范围:所有算法操作的区间都是左闭右开 [first, last),即包含 first 但不包含 last
  2. 有效性:确保目标范围有足够的空间,或使用 back_inserter 等插入迭代器。
  3. 排序要求binary_searchlower_boundmergeset_* 等算法要求输入范围已排序。
  4. 谓词:许多算法接受自定义谓词(函数指针、lambda 表达式、函数对象),确保谓词不修改元素(除非算法允许)。
  5. 复杂度:熟悉算法的复杂度,选择合适的算法(如 sort 通常优于 stable_sort 若不需要稳定性)。
  6. C++20 范围算法:使用范围版本时注意返回值类型,通常返回结构体包含迭代器,便于获取更多信息。
  7. constexpr:虽然许多算法现在是 constexpr,但标准库的实现可能要求迭代器操作也是 constexpr,因此在编译时使用受限。

结语

STL 算法是 C++ 标准库的精华,C++20 的范围库让它们更加强大和易用。熟练掌握这些算法可以让我们写出更简洁、高效且易于维护的代码。本文列举的算法覆盖了日常开发中绝大部分需求,并结合 C++20 新特性提供了更新。建议在实践中多使用、多查阅,逐渐内化于心。

(注:本文基于 C++20 标准,部分 C++23 特性未涉及,请参考具体编译器支持情况。)


C++ STL 常用算法详解
https://www.psnow.sbs/2026/02/23/C-STL-常用算法详解/
作者
Psnow
发布于
2026年2月24日
许可协议