【问题标题】:why can't I call `ranges::begin` on a `const filter_view`?为什么我不能在 `const filter_view` 上调用 `ranges::begin`?
【发布时间】:2021-02-25 09:45:18
【问题描述】:

我无法通过const filter_view 拨打ranges::begin

https://en.cppreference.com/w/cpp/ranges/filter_view beginend 似乎不是 const。这是为什么呢?

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);
}

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

【问题讨论】:

标签: c++ std-ranges


【解决方案1】:

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

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

所以这很有意义 - 因为可以(并且很可能是)一个内部状态 begin() 和/或 end() 可以修改它们不能被 const 修改。

【讨论】:

  • 为什么提升过滤范围与 const 一起使用?godbolt.org/z/Ge1cb8
  • @Hui 大概是因为它的设计并不懒惰......或者也许是,但他们使用mutable 成员,虽然我不知道这是否是一个可行的设计。
猜你喜欢
  • 2020-09-22
  • 2021-08-12
  • 1970-01-01
  • 1970-01-01
  • 2013-01-17
  • 1970-01-01
  • 2012-08-19
  • 2022-11-24
  • 2010-09-09
相关资源
最近更新 更多