std::views视图处理输入范围致程序非法的解决方案问询
std::views::transform 与不可重复访问输入范围的合法性疑问
问题场景
- 程序1:通过
std::views::istream获取非forward_range类型的input_range,经std::views::chunk(2)和std::views::transform折叠后输出"37",但该程序实际属于非法代码。 - 程序2:重复解引用迭代器后输出"30",出现同一迭代器位置值不一致的异常问题。
问题原因
std::views::transform要求其转换函数满足std::regular_invocable约束:而作为参数的chunk是不可重复访问的输入范围,每次调用转换函数都会消耗该范围,违反了regular_invocable“不可修改参数、重复调用需返回一致结果”的要求。
现有方案的局限
提案P3138中的views::cache_last可以避免重复求值,但即便使用它,这类程序依然不具备合法性。
核心提问
是否有计划让添加views::cache_last后的此类程序成为合法代码?比如给std::views::transform增加cache_last选项?
回答
目前C++标准委员会没有公开计划给std::views::transform内置cache_last选项,也没明确认可搭配views::cache_last的这类场景属于合法范围。
std::views::transform的设计核心是依赖regular_invocable的纯函数式转换,这是视图组合的基础规则——同一参数多次调用必须返回一致结果,且不能修改参数。不可重复访问的输入范围本身就打破了这个规则,views::cache_last只是缓存结果的“补丁”,没法从根本上让这类场景合规。
要处理这种情况,更合规的做法是:
- 先把不可重复访问的输入范围转成可重复访问的类型(比如把数据读到容器里),再用
std::views::transform - 自定义符合
regular_invocable要求的转换函数,保证每次调用不会消耗输入范围
内容的提问来源于stack exchange,提问作者nilo
相关产品推荐
相关产品推荐

