在 C++20 中,<algorithm>头文件中的许多算法被引入了 std::ranges命名空间,这些算法支持范围(Range)概念,提供了更现代、更安全的接口。以下是 C++20 std::ranges中主要的算法分类和示例:


1. 不修改序列的算法(Non-modifying)

  • 查找类
    • ranges::find/ ranges::find_if/ ranges::find_if_not
    • ranges::find_first_of
    • ranges::adjacent_find
    • ranges::search/ ranges::search_n
    • ranges::find_end
    • ranges::binary_search(需范围有序)
    • ranges::lower_bound/ ranges::upper_bound/ ranges::equal_range(需范围有序)
  • 计数类
    • ranges::count/ ranges::count_if
  • 比较类
    • ranges::equal
    • ranges::mismatch
    • ranges::lexicographical_compare
  • 检查类
    • ranges::all_of/ ranges::any_of/ ranges::none_of
    • ranges::starts_with/ ranges::ends_with(C++23)

2. 修改序列的算法(Modifying)

  • 复制类
    • ranges::copy/ ranges::copy_if
    • ranges::copy_n
    • ranges::copy_backward
  • 移动类
    • ranges::move/ ranges::move_backward
  • 填充类
    • ranges::fill/ ranges::fill_n
  • 生成类
    • ranges::generate/ ranges::generate_n
  • 删除类
    • ranges::remove/ ranges::remove_if
    • ranges::remove_copy/ ranges::remove_copy_if
  • 替换类
    • ranges::replace/ ranges::replace_if
    • ranges::replace_copy/ ranges::replace_copy_if
  • 去重类
    • ranges::unique/ ranges::unique_copy
  • 交换类
    • ranges::swap_ranges
    • ranges::reverse/ ranges::reverse_copy
    • ranges::rotate/ ranges::rotate_copy
    • ranges::shift_left/ ranges::shift_right(C++23)

3. 划分与排序算法(Partitioning/Sorting)

  • 划分类
    • ranges::partition/ ranges::stable_partition
    • ranges::partition_copy
    • ranges::is_partitioned
    • ranges::partition_point
  • 排序类
    • ranges::sort/ ranges::stable_sort
    • ranges::partial_sort/ ranges::partial_sort_copy
    • ranges::nth_element
    • ranges::is_sorted/ ranges::is_sorted_until

4. 堆操作(Heap Operations)

  • ranges::make_heap/ ranges::push_heap/ ranges::pop_heap
  • ranges::sort_heap
  • ranges::is_heap/ ranges::is_heap_until

5. 集合操作(Set Operations)

  • 有序范围操作
    • ranges::merge/ ranges::inplace_merge
    • ranges::includes
    • ranges::set_difference/ ranges::set_intersection
    • ranges::set_symmetric_difference/ ranges::set_union

6. 排列与组合(Permutations)

  • ranges::next_permutation/ ranges::prev_permutation
  • ranges::is_permutation

7. 数值操作(Numeric)

  • <numeric>中的范围版本
    • ranges::iota(C++23)
    • 其他数值算法(如 reducetransform_reduce)尚未完全引入范围版本。

关键改进

  1. 支持范围(Range):直接接受容器或视图,无需迭代器对(如 std::vector<int> v; ranges::sort(v);)。
  2. 投影(Projection):通过 std::identity或自定义投影函数灵活处理元素(如 ranges::sort(v, {}, &Person::age))。
  3. 约束(Constrained):使用概念(Concepts)约束参数类型,编译期错误更友好。

示例代码

#include <algorithm>
#include <vector>
#include <ranges>

int main()
{
std::vector<int> v = {3, 1, 4, 1, 5};

// 范围排序(升序)
std::ranges::sort(v);

// 使用投影按绝对值排序
std::ranges::sort(v, std::less{}, [](int x) { return std::abs(x); });

// 查找第一个偶数
auto it = std::ranges::find_if(v, [](int x) { return x % 2 == 0; });

// 视图过滤(C++20 视图)
auto even = v | std::views::filter([](int x) { return x % 2 == 0; });
}

总结

C++20 的 std::ranges算法提供了更简洁、安全的接口,结合范围(Range)、视图(View)和投影(Projection)等特性,显著提升了代码的可读性和表达能力。