c++ - range v3 展平序列

标签 c++ iterator stl-algorithm range-v3

所以我最近看了这个关于 c++ 的演讲: https://www.youtube.com/watch?v=mFUXNMfaciE

而且我非常有兴趣尝试一下。因此,在一些玩具程序之后,我一直在研究如何将 vector 的 vector 正确地展平为一个 vector 。根据此处的文档:https://ericniebler.github.io/range-v3/这可以使用 ranges::view::for_each 实现。但是我似乎无法让它工作。这是一些最少的代码。

#include <range/v3/all.hpp>
#include <iostream>
#include <vector>

int main()
{
    auto nums = std::vector<std::vector<int>>{
        {0, 1, 2, 3},
        {5, 6, 7, 8},
        {10, 20},
        {30},
        {55}
    };

    auto filtered = nums
        | ranges::view::for_each([](std::vector<int> num) { return ranges::yield_from(num); })
        | ranges::view::remove_if([](int i) { return i % 2 == 1; })
        | ranges::view::transform([](int i) { return std::to_string(i); });

    for (const auto i : filtered)
    {
        std::cout << i << std::endl;
    }
}

最佳答案

range-v3 错误消息往往非常可怕,以至于这个实际上比大多数都好:

prog.cc: In lambda function:
prog.cc:16:90: error: no match for call to '(const ranges::v3::yield_from_fn) (std::vector<int>&)'
         | ranges::view::for_each([](std::vector<int> num) { return ranges::yield_from(num); })
                                                                                          ^
In file included from /opt/wandbox/range-v3/include/range/v3/view.hpp:38:0,
                 from /opt/wandbox/range-v3/include/range/v3/all.hpp:21,
                 from prog.cc:1:
/opt/wandbox/range-v3/include/range/v3/view/for_each.hpp:133:17: note: candidate: template<class Rng, int _concept_requires_132, typename std::enable_if<((_concept_requires_132 == 43) || ranges::v3::concepts::models<ranges::v3::concepts::View, T>()), int>::type <anonymous> > Rng ranges::v3::yield_from_fn::operator()(Rng) const
             Rng operator()(Rng rng) const
                 ^~~~~~~~

to someone with a bit of knowledge of range-v3's concepts emulation layer, this "clearly" states that the call to yield_from failed because the type of the argument you passed to it - std::vector<int> - does not satisfy the View concept.

The View concept characterizes a subset of ranges that do not own their elements, and therefore have all operations - move/copy construction/assignment, begin, end, and default construction - computable in O(1). The range composition algrebra in range-v3 works only on views to avoid having to deal with element lifetimes and to provide predictable performance.

yield_from rejects the std::vectors you are trying to pass since they are not views, but you could easily provide views by (1) taking the vectors as lvalues instead of by value in for_each, and (2) yielding view::all of those lvalues [DEMO]:

auto filtered = nums
    | ranges::view::for_each([](std::vector<int>& num) {
        return ranges::yield_from(ranges::view::all(num)); })
    | ranges::view::remove_if([](int i) { return i % 2 == 1; })
    | ranges::view::transform([](int i) { return std::to_string(i); });

但在这种简单的情况下,将一系列元素的范围展平为一系列元素已经在 range-v3 中具有特定用途的 View :view::join。您也可以使用 [ DEMO ]:

auto filtered = nums
    | ranges::view::join
    | ranges::view::remove_if([](int i) { return i % 2 == 1; })
    | ranges::view::transform([](int i) { return std::to_string(i); });

关于c++ - range v3 展平序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43577873/

相关文章:

algorithm - 排列数列,使相邻数之和为质数

c++ - 使用 SDL_Flip 的 SDL 视频叠加层闪烁

c++ - 更改整个控制台背景颜色 (Win32 C++)

java - 为什么在迭代期间从映射中删除不存在的元素有时只会崩溃?

c++ - 是否在空的初始化程序列表(并明确指定类型)上调用 std::min 未定义的行为?

c++ - 是否允许标准库算法复制谓词参数?

c++ - 在 C++ API 上公开的基本类型

c++ - std::future 在 Boost UDP 套接字异步接收操作中不起作用

c++ - 从整数索引 for 循环枚举到范围 for

ruby-on-rails - 在 Ruby on Rails 中使用多个迭代器进行索引