std::views::drop 是 C++20 Range 库中用于跳过序列前 N 个元素并返回剩余部分视图的零拷贝、惰性求值适配器,要求范围满足 forward_range 概念,支持链式组合与自定义类型扩展。

如果您在使用 C++20 或更高标准的 Range 库处理序列时,需要跳过容器开头的若干元素并获取剩余部分的视图,则 std::views::drop 提供了一种零拷贝、惰性求值的解决方案。以下是该特性的详细说明与多种使用方式:
一、基本语法与构造行为
std::views::drop 是一个范围适配器对象,接受一个整型参数 N,返回一个视图,该视图从原始范围的第 N 个元素开始(索引从 0 起),跳过前 N 个元素。若 N 大于等于原范围大小,则返回空视图;若 N 为负数,则行为未定义,编译器通常拒绝该调用。
1、声明一个 std::vector
2、使用 std::views::drop(2) 作用于 v,得到视图 view = v | std::views::drop(2);
立即学习“C++免费学习笔记(深入)”;
3、遍历 view 将依次输出 3、4、5,不产生副本且不修改原容器。
二、与迭代器等价关系说明
std::views::drop(N) 的语义等价于对原始范围调用 std::ranges::next(std::ranges::begin(r), N),再以该位置为起始构造子范围。它要求底层范围至少满足 std::ranges::forward_range 概念,对随机访问范围(如 vector、array)可常数时间定位,对单向范围(如 list)则需线性时间推进迭代器。
1、对 std::list
2、auto dropped = lst | std::views::drop(1);
3、dropped.begin() 实际调用 std::next(lst.begin(), 1),指向值为 20 的节点。
三、结合其他视图适配器链式使用
std::views::drop 支持管道操作符(|),可与其他标准视图(如 filter、transform、take)组合,形成表达力强且高效的处理链。其惰性特性确保中间步骤不立即执行,仅在最终遍历时按需计算。
1、定义 std::vector<:string> words = {"a", "bb", "ccc", "dd", "e"};
2、构造链式视图:auto result = words | std::views::drop(1) | std::views::filter([](const auto& s) { return s.size() > 2; });
3、该链跳过首元素后筛选长度大于 2 的字符串,最终仅包含 "ccc"。
四、处理边界情况与安全检查
当传入的 N 超出范围时,std::views::drop 不抛异常也不断言,而是静默返回空视图。这要求调用者自行确保逻辑合理性,或在关键路径中显式验证 N 是否有效。
1、获取容器大小 size = std::ranges::size(r);
2、确认 N 在合法区间:if (static_cast
3、安全调用:auto safe_drop = r | std::views::drop(std::min(N, static_cast
五、自定义类型支持条件
要使用户自定义类型 T 支持 std::views::drop,该类型必须满足 std::ranges::range 概念,并提供符合要求的 begin()/end() 成员函数或非成员重载,且其迭代器类型需满足 std::input_iterator 或更高概念。
1、为 struct MyRange 定义嵌套类型 iterator 和 sentinel,满足 std::input_iterator 约束;
2、实现 consteval bool enable_borrowed_range
3、添加非成员 begin(MyRange&) 和 end(MyRange&) 函数;
4、此时 MyRange 实例即可参与 std::views::drop(N) 操作。


















