什么时候应该使用 STL 算法而不是使用自己的算法?

发布于 2024-09-08 17:21:30 字数 201 浏览 3 评论 0 原文

我经常使用 STL 容器,但从未使用过与 STL 容器一起使用的 STL 算法。

使用 STL 算法的一个好处是它们提供了一种消除循环的方法,从而降低了代码逻辑复杂性。还有其他好处,这里就不一一列举了。

我从未见过使用 STL 算法的 C++ 代码。从网页文章中的示例代码到开源项目,我还没有看到它们的使用。

它们的使用是否比看起来更频繁?

I frequently use the STL containers but have never used the STL algorithms that are to be used with the STL containers.

One benefit of using the STL algorithms is that they provide a method for removing loops so that code logic complexity is reduced. There are other benefits that I won't list here.

I have never seen C++ code that uses the STL algorithms. From sample code within web page articles to open source projects, I haven't seen their use.

Are they used more frequently than it seems?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

情话墙 2024-09-15 17:21:30

简短的回答:总是。

长答案:总是。这就是他们存在的目的。它们针对与 STL 容器一起使用进行了优化,并且比您自己编写的任何内容更快、更清晰、更惯用。您应该考虑自己推出的唯一情况是,如果您能够阐明 STL 算法无法满足的非常具体的关键任务需求。

编辑添加:(好吧,所以并不总是真的,但如果你必须问是否应该使用STL,答案是“是”。)

Short answer: Always.

Long answer: Always. That's what they are there for. They're optimized for use with STL containers, and they're faster, clearer, and more idiomatic than anything you can write yourself. The only situation you should consider rolling your own is if you can articulate a very specific, mission-critical need that the STL algorithms don't satisfy.

Edited to add: (Okay, so not really really always, but if you have to ask whether you should use STL, the answer is "yes".)

情定在深秋 2024-09-15 17:21:30

你已经得到了很多答案,但我不能真正同意其中任何一个。有一些相当接近目标,但没有提到关键点(当然,在我看来)。

至少对我来说,关键点非常简单:当标准算法有助于澄清您正在编写的代码时,您应该使用它们。

真的就是这么简单。在某些情况下,您正在做的事情需要使用 std::bind1ststd::mem_fun_ref (或类似顺序的东西)进行神秘的调用,这是非常密集和不透明的,其中 for 循环几乎非常简单和直接。在这种情况下,请继续使用 for 循环。

如果没有标准算法可以完成您想要的操作,请小心并再看一遍 - 您经常会错过一些真正可以完成您想要的操作的东西(经常错过的一个地方: 中的算法; 通常对于非数字用途很有用)。看了几次,并确认确实没有标准算法来完成您想要的事情,而不是内联编写 for 循环(或其他内容),请考虑编写一个通用算法来完成你需要做的事情。如果您在一个地方使用它,那么您很有可能可以再使用它两到三个,此时它可以在清晰度方面取得巨大胜利。

编写通用算法并不那么困难——事实上,与编写内联循环相比,它通常几乎不需要额外的工作,因此即使您只能使用它两次,您也已经节省了一些工作,即使您忽略代码可读性和清晰度的改进。

You've gotten a number of answers already, but I can't really agree with any of them. A few come fairly close to the mark, but fail to mention the crucial point (IMO, of course).

At least to me, the crucial point is quite simple: you should use the standard algorithms when they help clarify the code you're writing.

It's really that simple. In some cases, what you're doing would require an arcane invocation using std::bind1st and std::mem_fun_ref (or something on that order) that's extremely dense and opaque, where a for loop would be almost trivially simple and straightforward. In such a case, go ahead and use the for loop.

If there is no standard algorithm that does what you want, take some care and look again -- you'll often have missed something that really will do what you want (one place that's often missed: the algorithms in <numeric> are often useful for non-numeric uses). Having looked a couple of times, and confirmed that there's really not a standard algorithm to do what you want, instead of writing that for loop (or whatever) inline, consider writing an generic algorithm to do what you need done. If you're using it one place, there's a pretty good chance you can use it two or three more, at which point it can be a big win in clarity.

Writing generic algorithms isn't all that hard -- in fact, it's often almost no extra work compared to writing a loop inline, so even if you can only use it twice you're already saving a little bit of work, even if you ignore the improvement in the code's readability and clarity.

嘿哥们儿 2024-09-15 17:21:30

只要 STL 算法适合您的需要,就应该使用它们。这几乎是所有的时间。

STL algorithms should be used whenever they fit what you need to do. Which is almost all the time.

深巷少女 2024-09-15 17:21:30

什么时候应该使用 STL 算法而不是使用自己的算法?

当你珍惜自己的时间和理智,并且有比一次又一次重新发明轮子更有趣的事情去做时。

当项目需要时,您需要使用自己的算法,并且没有可以接受的替代方案来自己编写东西,或者如果您将 STL 算法确定为瓶颈(当然使用探查器),或者有某种 STL 没有的限制符合或调整 STL 来完成任务将比从头开始编写算法花费更长的时间(我不得不使用扭曲版本的二分搜索几次......)。 STL 并不完美,也不适合所有情况,但当可以时,您应该使用它。当某人已经为您完成了所有工作时,通常没有理由再次做同样的事情。

When should the STL algorithms be used instead of using your own?

When you value your time and sanity and have more fun things to do than reinventing the wheel again and again.

You need to use your own algorithms when project demands it, and there are no acceptable alternatives to writing stuff yourself, or if you identified STL algorithm as a bottleneck (using profiler, of course), or have some kind of restrictions STL doesn't conform to, or adapting STL for the task will take longer than writing algorithm from scratch (I had to use twisted version of binary search few times...). STL is not perfect and isn't fit for everything, but when you can, you should use it. When someone already did all the work for you, there is frequently no reason to do the same thing again.

柠栀 2024-09-15 17:21:30

我编写性能关键的应用程序。这些事情需要尽可能快地处理数百万条信息。如果没有STL,我就不可能做现在所做的一些事情。始终使用它们。

I write performance critical applications. These are the kinds of things that need to process millions of pieces of information in as fast a time as possible. I wouldn't be able to do some of the things that I do now if it weren't for STL. Use them always.

时光匆匆的小流年 2024-09-15 17:21:30

除了 std::foreach 之类的算法之外,还有许多好的算法。

然而,有很多重要且非常有用的算法:

  • 排序:std::sortstd::upper_boundstd::lower_bound , std::binary_search
  • 最小值/最大值 std::max, std::min, std::partitionstd::min_elementstd::max_element
  • 搜索 std::findstd::find_first_of 等 。

还有很多其他的

std::transform 这样的算法对于 C++0x lambda 表达式或者像 boost::lambdaboost::bind 之类的东西非常有用

There are many good algorithms besides stuff like std::foreach.

However there are lots of non-trivial and very useful algorithms:

  • Sorting: std::sort, std::upper_bound, std::lower_bound, std::binary_search
  • Min/Max std::max, std::min, std::partition, std::min_element, std::max_element
  • Search like std::find, std::find_first_of etc.

And many others.

Algorithms like std::transform are much useful with C++0x lambda expressions or stuff like boost::lambda or boost::bind

娇纵 2024-09-15 17:21:30

如果我必须在今天下午写一些东西,并且我知道如何使用手工循环来完成它,并且需要弄清楚如何在 STL 算法中完成它,我会使用手工循环来编写它。

话虽如此,出于其他答案中阐明的原因,我会努力使 STL 算法成为我工具包的可靠部分。

--

您可能在代码中看不到它的原因是它要么是遗留代码,要么是由遗留程序员编写的。在 STL 出现之前,我们已经进行了大约 20 年的 C++ 编程,那时我们有一个程序员社区,他们知道如何用旧的方式做事,但还没有学习 STL 的方式。这可能会持续一代人。

If I had to write something due this afternoon, and I knew how to do it using hand-made loops and would need to figure out how to do it in STL algorithms, I would write it using hand-made loops.

Having said that, I would work to make the STL algorithms a reliable part of my toolkit, for reasons articulated in the other answers.

--

Reasons you might not see it is in code is that it is either legacy code or written by legacy programmers. We had about 20 years of C++ programming before the STL came out, and at that point we had a community of programmers who knew how to do things the old way and had not yet learned the STL way. This will likely remain for a generation.

海风掠过北极光 2024-09-15 17:21:30

请记住,STL 算法涵盖了很多基础,但大多数 C++ 开发人员最终可能会编写一些与 std::find()std::find_if( )std::max() 几乎他们工作生活中的每一天(如果他们还没有使用 STL 版本)。通过使用 STL 版本,您将算法与代码的逻辑流和数据表示分离

对于其他不太常用的 STL 算法,例如 std::merge() 或 std::lower_bound() ,这些是非常有用的例程(第一个用于合并两个排序的容器,第二个用于确定将物品插入容器中的何处以保持其有序)。如果您尝试自己实现它们,那么可能需要进行几次尝试(算法并不复杂,但您可能会遇到一一错误等)。

我自己在职业生涯中每天都在使用它们。一些早于稳定 STL 的遗留代码库可能不会广泛使用它,但如果有一个新项目故意避免使用它,我会倾向于认为它是由一个仍然仍然的兼职黑客所为。在 90 年代中期的假设下,模板很慢,因此应该避免。

Bear in mind that the STL algorithms cover a lot of bases, but most C++ developers will probably end up coding something that does something equivalent to std::find(), std::find_if() and std::max() almost every day of their working lives (if they're not using the STL versions already). By using the STL versions you separate the algorithm from both the logical flow of your code and from the data representation.

For other less commonly used STL algorithms such as std::merge() or std::lower_bound() these are hugely useful routines (the first for merging two sorted containers, the second for working out where to insert an item in a container to keep it ordered). If you were to try to implement them yourself then it would probably take a few attempts (the algorithms aren't complicated, but you'd probably get off-by-one errors or the like).

I myself use them every day of my professional career. Some legacy codebases that predate a stable STL may not use it as extensively, but if there's a newer project that is intentionally avoiding it I would be inclined to think it was by a part-time hacker who was still labouring under the mid-90's assumption that templates are slow and therefore to be avoided.

感情废物 2024-09-15 17:21:30

我唯一不使用 STL 算法的时候是当跨平台实现差异影响我的程序结果时。这种情况只发生在一两种罕见的情况下(在 PlayStation 3 上)。尽管 STL 的接口是跨平台标准化的,但其实现却并非如此。

此外,在某些极高性能的应用程序中(例如:视频游戏、视频游戏服务器),我们用自己的结构替换了一些 STL 结构,以提高效率。

然而,绝大多数时候使用 STL 是正确的选择。在我的其他(非视频游戏)工作中,我专门使用 STL。

The only time I don't use STL algorithms is when the cross-platform implementation differences affect the outcome of my program. This has only happened in one or two rare cases (on the PlayStation 3). Although the interface of the STL is standardized across platforms, the implementation is not.

Also, in certain extremely high performance applications (think: video games, video game servers) we replaced a some STL structures with our own to eke out a bit more efficiency.

However, the vast majority of the time using STL is the way to go. And in my other (non-video game) jobs, I used the STL exclusively.

平定天下 2024-09-15 17:21:30

到目前为止,STL 算法的主要问题是,即使算法调用本身更清晰,定义您需要传递给它们的函子也会使您的代码更长、更复杂,这是由于语言强迫您这样做的方式它。 C++0x 有望改变这一现状,因为它支持 lambda 表达式。

在过去的六年里,我一直在大量使用 STL,尽管我尝试在任何可能的地方使用 STL 算法,但在大多数情况下,这会让我的代码变得更加晦涩,所以我又回到了一个简单的循环。现在使用 C++0x 则相反,使用它们代码似乎总是看起来更简单。

问题是,到目前为止,C++0x 支持仍然仅限于少数编译器,即使该标准尚未完全完成。因此,我们可能需要等待几年才能真正看到 STL 算法在生产代码中的广泛使用。

The main problem with STL algorithms until now was that, even though the algorithm call itself clearer, defining the functors that you'd need to pass to them would make your code longer and more complex, due to the way the language forced you to do it. C++0x is expected to change that, with its support for lambda expressions.

I've been using STL heavily for the past six years and although I tried to use STL algorithms anywhere I could, in most instances it would make my code more obscure, so I got back to a simple loop. Now with C++0x is the opposite, the code seems to always look simpler with them.

The problem is that by now C++0x support is still limited to a few compilers, even because the standard is not completely finished yet. So probably we will have to wait a few years to really see widespread use of STL algorithms in production code.

蝶舞 2024-09-15 17:21:30

在两种情况下我不会使用 STL:

  1. 当 STL 不是为您的任务而设计时。 STL 几乎是通用目的的最佳选择。然而,对于特定的应用程序,STL 可能并不总是最好的。例如,在我的一个程序中,我需要一个巨大的哈希表,而 STL/tr1 的 hashmap 等价物占用了太多内存。

  2. 当你学习算法时。我是少数几个喜欢重新发明轮子并在这个过程中学到很多东西的人之一。对于该程序,我重新实现了一个哈希表。确实花了我很多时间,但最终所有的努力都得到了回报。我学到了很多东西,对我未来作为程序员的职业生涯大有裨益。

I would not use STL in two cases:

  1. When STL is not designed for your task. STL is nearly the best for general purposes. However, for specific applications STL may not always be the best. For example, in one of my programs, I need a huge hash table while STL/tr1's hashmap equivalence takes too much memory.

  2. When you are learning algorithms. I am one of the few who enjoy reinventing the wheels and learn a lot in this process. For that program, I reimplemented a hash table. It really took me a lot of time, but in the end all the efforts paid off. I have learned many things that greatly benefit my future career as a programmer.

忱杏 2024-09-15 17:21:30

当你认为你可以比一个真正聪明的编码员更好地编码时,他花了数周的时间研究和测试并试图应对每一个可以想象的输入集。

对于大多数地球人来说,答案是永远

When you think you can code it better than a really clever coder who spent weeks researching and testing and trying to cope with every conceivable set of inputs.

For most Earthlings the answer is never!

热情消退 2024-09-15 17:21:30

我想用一个清晰​​的例子来回答“何时不使用STL”的情况。

(作为对你们所有人的挑战,请告诉我您可以使用 C++17 之前的任何 STL 算法来解决此问题)

将整数向量 std::vector 转换为 std::vector 向量code>std::pair,即:

转换

std::vector<int> values = {1,2,3,4,5,6,7,8,9,10};

std::vector<std::pair<int,int>> values = { {1,2}, {3,4} , {5,6}, {7,8} ,{9,10} };

你猜怎么着? 在 C++17 之前,任何 STL 算法都是不可能的。

请参阅此处解决此问题的完整讨论:

如何我将 std::vector 转换为到 std::vector> 对的向量使用 STL 算法?

所以回答你的问题:仅当它完全适合你的问题时才使用 STL 算法。不要修改 STL 算法来使其适合您的问题。

I want to answer the "when not to use STL" case, with a clear example.

(as a challenge to all of you, show me that you can solve this with any STL algorithm until C++17)

Convert a vector of integers std::vector<int> into a vector of std::pair<int,int>, i.e.:

Convert

std::vector<int> values = {1,2,3,4,5,6,7,8,9,10};

to

std::vector<std::pair<int,int>> values = { {1,2}, {3,4} , {5,6}, {7,8} ,{9,10} };

And guess what? It's impossible with any STL algorithm until C++17.

See the complete discussion on solving this problem here:

How can I convert std::vector<T> to a vector of pairs std::vector<std::pair<T,T>> using an STL algorithm?

So to answer your question: Use STL algorithm always only when it perfectly fits your problem. Don't hack an STL algorithm to make it fit your problem.

旧城烟雨 2024-09-15 17:21:30

它们的使用是否比看起来更频繁?

我从未见过它们被使用过;除了书本上。也许它们被用于 STL 本身的实现。也许它们会因为更容易使用而变得更常用(例如参见 Lambda 函数和表达式),甚至变得过时(例如,参见 基于范围的 for 循环),在下一版本的 C++ 中。

Are they used more frequently than it seems?

I've never seen them used; except in books. Maybe they're used in the implementation of the STL itself. Maybe they'll become more used because easier to use (see for example Lambda functions and expressions), or even become obsoleted (see for example the Range-based for-loop), in the next version of C++ .

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文