简体   繁体   English

使用 C++20 范围来避免循环

[英]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:约束条件:

  • no loops or recursion没有循环或递归
  • no std::for_each没有std::for_each
  • no data structures other than std::vector除了std::vector之外没有其他数据结构
  • no memory allocation (other than a one-time allocation for the return vector)没有 memory 分配(返回向量的一次性分配除外)
  • no by-reference lambda captures or mutable lambdas没有引用 lambda 捕获或可变 lambda
  • cannot modify the input 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM