相关疑难解决方法(0)

range::view::transform 产生一个 InputIterator 阻止使用 std::prev

考虑以下代码,它使用 C++20 中的 Ranges 库:

#include <vector>
#include <ranges>
#include <iostream>

int main()
{
    std::vector<int> v{0,1,2,3,4,5,6,7};

    auto transformed = std::ranges::views::transform(v, [](int i){ return i * i; });

    std::cout << *std::prev(std::end(transformed));
}
Run Code Online (Sandbox Code Playgroud)

得知(至少在 GCC-10.3.0 和 GCC-12.0.0 下)这段代码卡在std::prev.

什么情况是,由于拉姆达不返回左值引用,transformed范围迭代器被列为输入迭代器(参见规则进行iterator_category选择的views::transform)。但是,std::prev 要求迭代器至少是双向迭代器,所以我猜这段代码实际上是UB。在 libstdc++ 中,应用于std::prev输入迭代器会导致此函数

template<typename _InputIterator, typename _Distance>
__advance(_InputIterator& __i, _Distance __n, input_iterator_tag)
{
    // concept requirements
    __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
    __glibcxx_assert(__n >= 0);
    while (__n--)
        ++__i;
}
Run Code Online (Sandbox Code Playgroud)

被调用__n == -1 …

c++ iterator c++20 std-ranges

4
推荐指数
1
解决办法
118
查看次数

标签 统计

c++ ×1

c++20 ×1

iterator ×1

std-ranges ×1