[英]Using C++20 Ranges to Avoid Loops
I was assigned a task where I need to solve a problem given several constraints.我被分配了一项任务,我需要在几个约束条件下解决一个问题。 The point is to enforce the use of STL algorithms, iterators, and new c++20 functionality including things like
ranges
.重点是强制使用 STL 算法、迭代器和新的 c++20 功能,包括
ranges
之类的功能。 However I've been reading on ranges for hours and I still can't figure out how I can implement the problem given all the constraints.但是,我已经阅读了数小时的范围,但我仍然无法弄清楚在所有约束条件下如何解决该问题。 I've simplified the problem and removed the specific details to make it more generic.
我简化了问题并删除了具体细节以使其更通用。
The Problem:问题:
Write a function that 1) takes in a vector of custom objects input
2) returns a vector of a different type that includes an element for each object in input
that satisfies some conditions.编写一个 function,它 1) 接收一个自定义对象的向量
input
2) 返回一个不同类型的向量,其中包含满足某些条件的input
中每个 object 的元素。 The value added is based on the properties of the input objects.添加的值基于输入对象的属性。
I realize this may sound obscure so here's a simple example.我意识到这听起来可能很晦涩,所以这里有一个简单的例子。 For an input vector of Shapes where each has a name and an area:
对于 Shapes 的输入向量,其中每个 Shapes 都有一个名称和一个区域:
vector<Shapes> input{ { "Square", 10 }, { "Triangle", 30 } , { "Square", 1 }, { "Circle", 30 }, { "Triangle", 15 } };
return a vector of enums返回一个枚举向量
enum Color { RED, BLUE, GREEN };
such that an enum is added for each Square or Circle.这样就为每个 Square 或 Circle 添加了一个枚举。 The value of the enum is determined based on the area of each Shape.
枚举的值是根据每个 Shape 的面积确定的。 So, let's say, if the area is above 20, RED is added, otherwise, GREEN is added.
因此,比方说,如果面积大于 20,则添加红色,否则添加绿色。
So in this case we'd return { GREEN, GREEN, RED }
所以在这种情况下我们会返回
{ GREEN, GREEN, RED }
This is all well and good and could be implemented in a myriad of ways, what makes it very difficult are the constraints.这一切都很好,可以通过多种方式实施,但限制因素使其变得非常困难。
The Constraints:约束条件:
std::for_each
std::for_each
std::vector
std::vector
之外没有其他数据结构My professor claims that "c++20 ranges make this task particularly simple."我的教授声称“c++20 范围使这项任务特别简单。” But even after reading on ranges for hours I'm not even sure where would I begin.
但即使在阅读了几个小时的范围之后,我什至不确定我从哪里开始。 My current train of thought is to create a
std::view
and filter
it based on the conditions (Squares & Circles) but then I'm not sure how I would create a new vector of a different type and add elements to it based on the properties of the elements in the view without using loops, for_each
, or by-reference lambdas..我目前的思路是创建一个
std::view
并根据条件(正方形和圆圈)对其进行filter
,但我不确定如何创建不同类型的新向量并根据条件向其添加元素不使用循环、 for_each
或引用 lambda 的视图中元素的属性。
If you simply want to transform every shape to an enum, all you need is:如果您只是想将每个形状转换为枚举,您只需要:
auto colors = input | transform([](const Shapes& s){return s.size > 20 ? RED : GREEN;});
colors
can then be looped through in a for-loop:然后可以在 for 循环中遍历
colors
:
for (const auto& c: colors)
Or be made into a new vector:或者做成一个新的vector:
std::vector<Color> colorEnums{colors.begin(), colors.end()};
...though C++23's ranges::to
would be helpful for the latter. ...尽管 C++23 的
ranges::to
对后者会有帮助。
If you want to only generate the color elements for some elements in your input vector (ex.: not triangles), add filter before transform, eg:如果您只想为输入向量中的某些元素生成颜色元素(例如:不是三角形),请在转换之前添加过滤器,例如:
auto colors = input |
filter([](const Shapes& s){return s.type != "Triangle";}) |
transform([](const Shapes& s){return s.size > 20 ? RED : GREEN;});
Note that having filter after transform would work too, but be less efficient, as the code would then transform all elements, before discarding some of them.请注意,在转换之后使用过滤器也可以,但效率较低,因为代码随后会转换所有元素,然后再丢弃其中一些元素。 So use filter as early as possible.
所以尽早使用过滤器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.