范围v3展平序列 [英] range v3 flattening a sequence
问题描述
所以我最近观看了有关c ++的演讲: https://www.youtube.com/watch?v=mFUXNMfaciE
So I recently watched this talk on c++: https://www.youtube.com/watch?v=mFUXNMfaciE
我对尝试它非常感兴趣.因此,在执行一些玩具程序之后,我将继续学习如何将向量的向量正确展平为向量.根据此处的文档: https://ericniebler.github.io/range-v3/使用ranges::view::for_each
可以做到这一点.但是我似乎无法使它正常工作.这是一些最少的代码.
And I was very interested on trying it out. So after some toy program I am stuck on how to properly flatten a vector of vectors into a vector. According to the documentation here: https://ericniebler.github.io/range-v3/ This is possible using ranges::view::for_each
. However I just can't seem to get it to work. Here is some minimal code.
#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错误消息往往非常可怕,以至于这个错误消息实际上比大多数情况都要好:
range-v3 error messages tend to be pretty horrible, so much so that this one is actually better than most:
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
^~~~~~~~
对于一些对range-v3的概念仿真层有一定了解的人,
清楚地指出,对yield_from
的调用失败了,因为传递给它的参数的类型-std::vector<int>
-不满足View
概念.
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.
View
概念表示不拥有其元素的范围子集的特征,因此具有所有操作-移动/复制构造/分配,开始,结束和默认构造-可在O(1)中计算. range-v3中的范围组成算法只在视图上起作用,以避免必须处理元素寿命并提供可预测的性能.
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
拒绝您尝试传递的std::vector
,因为它们不是视图,但是您可以通过(1)将向量作为左值代替for_each
中的值来轻松地提供视图,以及(2 )产生这些左值的view::all
[ DEMO ]:
yield_from
rejects the std::vector
s 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::join
.您也可以使用[ DEMO ]:
But in this simple case, flattening a range of ranges of elements into a range of elements already has a purpose-specific view in range-v3: view::join
. You may as well use that [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); });
这篇关于范围v3展平序列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!