为什么我不能在c++20中的istream_view之后使用take()

代码显示了我的问题,我不能使用take(3)之后istream_view

错误信息是:

/home/linuxbrew/.linuxbrew/Cellar/gcc/11.1.0_1/include/c++/11.1.0/ranges:1775:48: 错误:传递 'std::ranges::take_view<std::ranges::transform_view< std::ranges::basic_istream_view<int, char, std::char_traits >, int ( )(int)> >::_CI' {aka 'const std::counted_iterator<std::ranges::transform_view<std:: range::basic_istream_view<int, char, std::char_traits >, int ( )(int)>::_Iterator >'} 作为 'this' 参数丢弃限定符 [-fpermissive] 1775 | { 返回 __y.count() == 0 || __y.base() == __x._M_end; }

#include <ranges>

using namespace std::views;
using namespace std::ranges;
int to_sq(int a){return a*a;}
int main()
{

    auto m_range = istream_view<int>(std::cin);
    // error
    for (auto i : m_range | transform(to_sq)|take(3))
    {
        std::cout << i << std::endl;
    }
}

回答

这是LWG 3391。

transform这里是无关紧要的,只是想迭代istream_view<int>(std::cin) | views::take(3)已经是一个问题。从问题:

代码无效,因为ranges::take_view::sentinel::operator==()必须调用counted_iterator::base()底层迭代器与其哨兵进行比较,因此这operator==()要求底层迭代器是可复制构造的。

gcc 11.1 尚未包含此修复程序(特别是在 11.1 发布几周后发布的此提交),但 gcc trunk 现在包含了。


以上是为什么我不能在c++20中的istream_view之后使用take()的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>