You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何无法对const修饰的ranges::any_view调用ranges::begin?

ranges::any_view的const调用问题

问题代码与核心疑惑

以下代码执行失败:

#include <range/v3/view/any_view.hpp>
#include <vector>

int main() {
   std::vector<int> a{1};

   const ranges::any_view<int, ranges::category::forward> av(a);
   ranges::begin(av);
}

我原本认为begin会返回支持多次遍历的新迭代器,为什么它要求范围必须是可修改的?

我的实际代码场景如下:

void merge(ranges::any_view<int, ranges::category::forward> av) {
   for(auto x : av) { ... }
}

clang-tidy警告我应该把av改成const&,因为按值传递但没有在函数体内移动它,但改成const引用就会触发前面的调用失败问题。

对原因的推测

我怀疑这和begin/end调用的均摊常数时间复杂度要求有关。比如下面这段代码也会执行失败,原因应该是const的drop视图无法缓存begin的迭代器:

std::list<int> b{1, 2, 3, 4};

const auto latter = ranges::views::all(b) | ranges::views::drop(2);
ranges::begin(latter);

为了兼容这类被包装的视图,any_view需要缓存首次调用begin的结果,这就要求它能修改自身状态——因此const修饰的any_view无法调用begin,哪怕把类别改成random_access也不行:

const ranges::any_view<int, ranges::category::random_access> av(a);

寻求绕过方案

如果这确实是input类别下失败的原因,有没有什么绕过方法?比如类似C++23中std::move_only_function对std::function的移动语义扩展那样的方案?


内容的提问来源于stack exchange,提问作者Johannes Schaub - litb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 23:55:03