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

Posted

技术标签:

【中文标题】C++ 标准库 - 我应该啥时候使用它,啥时候不应该使用它?【英文标题】:C++ standard library - when should I use it and when shouldn't I?C++ 标准库 - 我应该什么时候使用它,什么时候不应该使用它? 【发布时间】:2011-01-21 22:08:34 【问题描述】:

我想知道人们实际使用大部分标准 c++ 库的频率,尤其是 <algorithm><numeric> 标头中的内容。教科书似乎推荐它们,但我还没有看到它们中的任何一个在我筛选过的各种项目中使用过(巧合?)而且就个人而言,每次自己编写适当的简单算法似乎更容易,而不是记忆或每次参考这些标题。只是懒惰还是固执?使用这些库时是否真的有性能提升等?

谢谢,

R

【问题讨论】:

+1 这是一个好问题,我希望更多的程序员会问。 +1 为库使用正确的名称。 【参考方案1】:

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

我这样做并不是为了炫耀,也不是因为我喜欢编写“太空时代代码”。相反,我这样做是因为我是一个偏执的程序员,而且我知道生产环境是充满敌意的地方,如果有机会的话,它们会破坏代码并使我的程序变成一堆冒烟的毫无价值的字节。

我这样做是因为我的座右铭是:“最好的代码,是你永远不会写的代码。”学习如何有效地使用 STL 和 Std Lib 需要时间,但是一旦你这样做了,你会发现它可以被使用,所以现在的 1000 行代码可能变成了 100 行。那些 100可能需要与原始 1000 一样长的时间来写入,但故障点更少。如果你站在别人的肩膀上,代码会更健壮。

【讨论】:

这看起来适用于几乎所有常见的库,不仅仅是 STL。 确实如此,但这取决于相关公共库的资格和文档 “只要有足够的眼球,所有的 bug 都很浅”。与几乎任何其他 C++ 项目相比,STL 无疑拥有更多的眼球。 @7vies:这就是 Boost 如此成功的原因 :) “这 100 个可能需要与原始 1000 个一样长的时间来写入,但故障点更少。”马上,包括第一部分(“可能需要很长时间”),这并不总是那么明显。一个完美的例子是 Koenig 的练习“计算每个单词在标准输入流中出现的次数”。 stdlib-heavy C++ version is tight & expressive。一个“糟糕”的 C++ 示例可能仍然使用 Std Lib,但可能会将内容推入向量中,然后再进行迭代和计数。而C版,你只能想象……【参考方案2】:

您应该尽可能使用 stl。 它是由相当老练的程序员编写的,您不太可能编写任何 stl 东西的更优化版本。 不要重新发明***

【讨论】:

... 它使用正确的类型,例如 size_tptrdiff_t 等。我刚刚发现 Qt 使用 int 来表示容器大小,这意味着它在 x86_64 上不是 64 位干净的. QT,因为它需要自己的预处理器 (moc),所以它并不是真正的 C/C++。【参考方案3】:

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

是否有性能提升显然取决于您所比较的对象。但总的来说,使用 STL 算法通常比编写自己的函数更快——除非您碰巧有一个适用于您的用例的特定技巧,可以为您带来优势。如果你自己写一个标准的快速排序,它可能会比 STL 中的慢。

【讨论】:

【参考方案4】:

什么时候应该使用 C++ 标准库?当它提供你需要的功能时。

众所周知,语言不能很好地支持诸如 for_each 之类的东西——这就是 lambda 在 C++0x 中的用途。

【讨论】:

我敢打赌,当大多数编译器正确支持 lambda 时,您会看到更多使用 for_each 的新代码。我个人不使用该函数(除非已经有一个免费函数可以执行我想要的操作),因为 BOOST_FOREACH 更内联。一旦 lambda 变得无处不在,我可能会在 BOOST_FOREACH 上使用 for_each 和 lambda。【参考方案5】:

您正在筛选哪些项目?这些专业项目还是随机的?

我注意到的一件事是,许多遗留类型代码(我在 C++98 之前的代码库上工作)由于当时实现的性能担忧而避免使用 C++ 标准库,或者只是因为当时这些库不存在。当然,某些环境(嵌入式系统、游戏、防御等)可能有其他要求,在许多情况下排除了使用 C++ 标准库,比如我的一个同事从事防御工作,根本无法使用 STL 的东西,因客户要求不使用。


一般来说,如果可以选择使用标准库、发明自己的***还是使用别人的库,那么一般来说,我会首先选择第一个选择。代码经过数千人、数十万人的测试,比您自己实现的大多数东西都要接受更多的测试和审查。

第三方库(让我们举一个像 Boost 这样的例子)如果它有你需要的东西。像 Boost 这样的库备受推崇,以卓越的代码质量而闻名,并且被很多很多人使用/测试/维护。

最后的选择是自己发明代码,我觉得这真的分为几类:

    自学 - 编写代码只是为了学习,但这意味着您不希望将其作为生产代码提供。 您有特定的要求,任何可以获取的东西都无法满足,或者必须从其他东西中调整。这其中有很多,您可能需要针对您正在做的任何事情编写自己的算法。

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

如果您可以将这种担忧转嫁给其他熟悉此类代码的开发人员,并让成千上万的人进行测试?这是一个巨大的胜利!

【讨论】:

【参考方案6】:

您应该使用所有语言的标准库,而不仅仅是 C++。这几乎是当今编程的基本规则。

你的印象是错误的;任何好的项目都将受益于建立在已知的、经过测试的库上。这些图书馆背后的时间和工时是个人无法单独完成的。

多年来,为了让这些图书馆正常运行,许多人遭受了苦难、流汗、发誓和战斗。编写、调试和争论每个特定实现细节的综合努力大概可以用 几十年 来衡量。最重要的是,为了确保一切都按照规范运行,我们花费了无数的机器周期来运行测试。

然而,几乎每个程序员都时不时有这种想法。你知道那个。

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

我知道。我明白。我去过那里。

继续。这是一次很好的体验。

一条漫长而曲折的道路将在您面前延伸。在您旅程的最初部分,您会在这里和那里发现很少的实施鹅卵石。其中一些会穿上你的鞋子,大多数不会。

稍后的路径将不再那么笔直;它会开始分支。很快你就会发现自己尝试了许多不同的路径并经常回溯。有时您会遇到算法不确定性的巨大鸿沟或令人厌烦的重构山。

当你看着你的同行在干净、笔直、维护良好的标准图书馆高速公路上超速行驶时。

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

总之 - 如果你想到达某个地方,无论你跑多快,开车都会让你更快、更安全地到达那里(除非你要去楼下的商店买牛奶)

【讨论】:

【参考方案7】:

很多现有的 C++ 项目不使用标准库,因为它们是在您可以依赖可用的标准库之前开始的——我说的是发布历史可以追溯到 10 到 15 年的代码,这里.我还听说一些现代环境(例如 android仍然没有为您提供完整的 C++ 运行时,因此如果您需要移植到这些环境中,您仍然无法使用它。

另一个原因是一些非常大的程序(我对 Firefox 的胆量有个人经验,而且我听说 OpenOffice 也是如此)是在禁用异常支持的情况下构建的,因为人们强烈认为它会导致性能问题(这实际上可能适用于 MSVC++ 的 ABI 和/或大小可笑的程序,例如上述两个)——但如果这样做,您将无法使用大部分 C++ 运行时。

这很令人沮丧,但这是适合你的行业。

【讨论】:

以上是关于C++ 标准库 - 我应该啥时候使用它,啥时候不应该使用它?的主要内容,如果未能解决你的问题,请参考以下文章

我啥时候应该在 C++ 中使用 typedef?

C++中啥时候出现不完整类型错误

我应该啥时候在堆上分配? (C++)

你啥时候在 C++ 中对一个结构进行 ZeroMemory 处理?

在 Windows 上,啥时候应该使用“\\\\?\\”文件名前缀?

servletcontext.getRealPath("/") 是啥意思,我应该啥时候使用它