为什么std::ranges::filter_view对象必须是非常量才能查询其元素?

#include <ranges>
#include <iostream>
#include <string_view>

using namespace std::literals;

int main()
{
    auto fn_is_l = [](auto const c) { return c == 'l'; };

    {
        auto v = "hello"sv | std::views::filter(fn_is_l);
        std::cout << *v.begin() << std::endl; // ok
    }

    {
        auto const v = "hello"sv | std::views::filter(fn_is_l);
        std::cout << *v.begin() << std::endl; // error
    }
}

请参阅:https : //godbolt.org/z/vovvT19a5

<source>:18:30: error: passing 'const std::ranges::filter_view<
                       std::basic_string_view<char>, main()::
                       <lambda(auto:15)> >' as 'this' argument discards
                       qualifiers [-fpermissive]
   18 |         std::cout << *v.begin() << std::endl; // error
      |                       ~~~~~~~^~
In file included from <source>:1:/include/c++/11.1.0/ranges:1307:7: 
     note: in call to 'constexpr std::ranges::filter_view<_Vp, 
           _Pred>::_Iterator std::ranges::filter_view<_Vp, Pred>
           ::begin() [with _Vp = std::basic_string_view<char>; _Pred =
           main()::<lambda(auto:15)>]'
 1307 |       begin()
      |       ^~~~~

为什么 对象必须std::ranges::filter_view 是非常量才能查询其元素?

回答

为了提供 所需的摊销常数时间复杂度rangefilter_view::begin将结果缓存在 中*this。这会修改 的内部状态,*this因此不能在const成员函数中完成。

  • That's curious if the result with or without the cache can be guaranteed to be the same. (Can it?) then mutable is an option right? const is all about the external api to an object not the internal state. It is non trivial to use mutable keyword correctly but it can be done.
  • @bradgonesurfing Right, technically this is possible, but this requires thread synchronization (to meet the requirement for `const` functions), which is deemed too expensive.
  • @dan04 - that no longer meets the time complexity requirements, at least from a pedantic point of view.
  • FYI: [P0789R3](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0789r3.pdf) 1.3.1 "The filter adaptor is not const-iterable" explains the design decision of `filter_view`.

以上是为什么std::ranges::filter_view对象必须是非常量才能查询其元素?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>