C++ 标准库 - 什么时候应该使用它,什么时候不应该?

39
我想知道人们实际上有多频繁地使用标准C++库,特别是在<algorithm><numeric>头文件中的内容。教科书似乎推荐使用它们,但我在各种项目中都没有看到过它们的使用(巧合吗?), 个人认为每次编写适当的简单算法比记忆或查阅这些头文件更容易。我是懒还是固执呢?使用这些库时是否真的能提高性能等方面的收益呢?
谢谢, R

+1 这是一个好问题,我希望更多的程序员能够提出这样的问题。 - John Dibling
1
如果使用正确的库名称,就给我加一分。 - Lightness Races in Orbit
7个回答

48

可能你懒惰或固执。就我个人而言,我在生产代码中经常使用它们。

我这么做并不是为了炫耀,也不是因为我喜欢编写“太空时代”的代码。相反,我这么做是因为我是一个多疑的程序员,我知道生产环境是充满敌意的地方,如果有机会的话,它们会毁掉我的代码,并将我的程序降为一堆无用的字节。

我这么做是因为我信奉“最好的代码是你从未编写过的代码”这个座右铭。学习如何有效地使用STL和Std Lib需要时间,但一旦你掌握了它们,你会发现它们可以被用来将现在的1000行代码变成可能只有100行。虽然这100行可能需要和原来1000行一样长的时间来编写,但是失败点会更少。如果你站在他人的肩膀上,代码可以更加健壮。


15
这似乎适用于几乎所有常见的库,而不仅仅是 STL。 - Roman L
2
这确实是可能的,但这取决于所涉及的公共库的质量和文档。 - John Dibling
6
足够多的眼睛,所有的漏洞都是肤浅的。STL拥有比其他几乎所有C++项目都要更多的关注者。 - André Paramés
1
@7vies:这就是为什么Boost如此成功的原因 :) - Matthieu M.
那100个任务可能需要和原来的1000个一样长的时间去写,但是失败点更少。这很正确,即使第一部分("might take as long")有时候并不那么显而易见。一个完美的例子是Koenig的练习“在标准输入流中计算每个单词出现的次数”。 [使用stdlib的C++版本紧凑且富有表现力](http://www.velocityreviews.com/forums/showpost.php?p=1533417&postcount=3)。一个“糟糕”的C ++示例仍然可能使用Std Lib,但是可能会将东西推入向量,然后稍后迭代和计算。至于C版本,你只能想象…… - Dan
另一个关于 C++ 标准库强大性的例子是C vs. C++问题,其中有一个示例程序...有C版本C++版本,以及"调优"后的C++版本 - Dan

8

尽可能多地使用STL。
它是由非常有经验的程序员编写的,你很难编写出任何STL内容更优化的版本。
不要重复造轮子。


2
它使用适当的类型,如size_tptrdiff_t等。我刚发现Qt在容器大小上使用int,这意味着在x86_64上它不是64位干净的。 - Fred Foo
QT,因为它需要自己的预处理器(moc),所以并不真正属于C/C++。 - KitsuneYMG

6

几乎每个使用C++的人都使用STL,尤其是<algorithm>。你真的不想自己编写排序函数;你最终只会犯错误,并且性能可能会更差。

显然,是否有性能提升取决于你要比较什么。总的来说,使用STL算法通常比编写自己的函数更快 - 除非你碰巧有一个适用于你的用例的特殊技巧可以给你优势。如果你自己编写标准快速排序,它可能比STL中的慢。


2

你何时应该使用C++标准库?当它提供你所需的函数时。

众所周知,像for_each这样的某些函数在语言方面的支持不是很好-这就是在C++0x中引入lambda表达式的原因。


我敢打赌,当大多数编译器正确支持lambda表达式时,你会看到更多使用for_each的新代码。个人而言,除非已经有一个自由函数可以做到我想要的,否则我不使用该函数,因为BOOST_FOREACH更加内联。一旦lambda变得普遍,我可能会使用for_each和lambda代替BOOST_FOREACH。 - KitsuneYMG

2
你在筛选哪些项目?这些是专业项目还是随意的?我注意到很多遗留代码(我曾经使用过一个比C++98更早的代码库)避免使用C++标准库,因为当时实现的性能担忧或者只是因为当时这些库不存在。当然,有些环境(嵌入式系统、游戏、国防等)可能有其他要求,在许多情况下排除了使用C++标准库的可能性,比如我的一位同事在国防领域工作,由于客户的要求不能使用STL,所以根本无法使用。


通常情况下,如果有选择使用标准库与自己发明轮子或使用别人的库,那么通常我会首先选择第一种选择。这段代码被数千、数十万人测试,接受比大多数你自己实现的东西更多的测试和审查。

如果第三方库(比如Boost)具备你需要的功能,那么就可以选择它。像Boost这样的库非常受人尊敬,具有优异的代码质量声誉,并且被许多人使用/测试/维护。

最后一种选择是自己编写代码,我认为这真的分为几类:

  1. 自我学习-编写代码只是为了学习,但这意味着你没有期望将其作为生产代码发布。
  2. 您有特定的要求,这些要求无法满足任何可以获得的东西,或必须从其他东西中进行调整。有很多这样的情况,你可能需要编写自己的算法,以针对你正在做的任何事情。

但请记住,如果您自己实现,请考虑标准库是否已经提供了它,否则,如果某些内容在您的代码中非常深入,那么您可能会遇到维护问题。我的上一个公司实现了他们自己的容器类,当然,代码库增长到数百万行(跨越大量产品),每个人都使用这些内部开发的容器类。这些容器中的错误会导致开发人员花费大量时间和金钱来修复,因为这些类中存在基本错误(链表、向量、关联数组,这些都是标准C++没有提供的)。虽然新代码使用标准库,但公司没有资源开始重构所有旧代码。

如果您可以转移这种担忧给其他有经验的开发人员,并获得成千上万人的测试?那是一个巨大的胜利!


1

在编程中,你应该使用所有语言中的标准库,而不仅仅是C++。这基本上是编程的基本规则。

你的印象是错误的;任何好的项目都将受益于建立在已知、经过测试的库之上。这些库背后所花费的时间和人力是一个人无法独自完成的。

多年来,许多人为了使这些库正常运行而遭受了苦难、流汗、发誓和斗争。编写、调试和争论每个特定实现细节的综合努力可能可以用“数十年”来衡量。此外,无数的机器周期已经花费在运行测试之后,只是为了确保一切都按照规格工作。

然而,几乎每个程序员都会有那样的想法。你知道那个。

“我可以在一个晚上做得更好。”

我知道。我理解。我也曾经历过。

去吧。这是一个很好的经验。

一条漫长而曲折的道路将在你面前延伸。在旅程的初期,你会发现一些小的实现问题。其中一些会滑进你的鞋子里,大多数则不会。

之后,编程之路将不再那么笔直,它会开始分叉。很快你会发现自己尝试了许多不同的路径,并经常需要回溯。有时你会遇到深奥的算法不确定性或繁琐的重构难题。

而与此同时,你会看着同行们在干净、笔直、维护良好的标准库高速公路上飞驰。

渐渐地,你会意识到拒绝使用标准库不仅是懒惰或固执,而且是愚蠢和极其低效的!

总之,如果你想要到达某个地方,无论你跑得多快,开车都能更快、更安全地带你到达(除非你只是去楼下买点牛奶)。


0

许多现有的C++项目不使用标准库,因为它们是在你不能依赖于标准库可用之前开始的 - 我说的是具有十到十五年发布历史的代码。我还听说一些现代环境(例如Android)仍然没有提供完整的C++运行时,因此如果您需要在这些环境中进行移植,则仍然无法使用它。

另一个原因是一些极大型程序(我个人有Firefox内部的经验,并且我听说OpenOffice也是如此)构建时禁用了异常支持,因为人们坚信它会导致性能问题(对于MSVC++的ABI和/或上述两个程序这可能实际上是真的)- 但如果这样做,您将无法使用大多数C++运行时。

这很令人沮丧,但这就是这个行业。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接