为什么我不能在 `const filter_view` 上调用 `ranges::begin` ?

Hui*_*Hui 6 c++ std-ranges

我无法ranges::begin致电const filter_view

https://en.cppreference.com/w/cpp/ranges/filter_view 和似乎不是begin。这是为什么?endconst

int main(){
    std::vector v{1,2,3};
    // removing const will make it compile
    const auto r = v | ranges::views::filter ([](auto&&){return true;}); 
    ranges::begin(r);
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/4feaYc

bar*_*top 4

图书馆中的所有视图在std::range设计上都是惰性的。这在实践中意味着什么?这意味着在底层,它们通常beginend常规容器在 和 迭代器操作上执行更多操作。通常为了能够维持这种惰性,需要一些内部状态。例如,filterred 视图可以将迭代器存储到最后一个匹配元素或类似的东西。在这种情况下begin()会更改此内部字段。甚至 cppreference 也对 begin 说了这样的话:

返回用 {*this, Ranges::find_if(base_, std::ref(*pred_))} 初始化的迭代器。为了提供范围概念所需的摊余常量时间复杂度,该函数将结果缓存在filter_view对象中以供后续调用使用。

所以它是完全有道理的 - 因为可以(并且很可能是)一个内部状态,begin()并且/或end()可以修改它们不能被创建const