STL有什么好处?

时间:2010-05-13 05:01:29

标签: c++ stl

我是一名尝试学习C ++的Java开发人员。我有很多次在互联网上阅读(包括Stack Overflow),STL是你可以用任何语言获得的最佳馆藏库。 (对不起,我没有任何引用)

然而,在研究了一些STL之后,我真的没有看到是什么让STL如此特别。您是否可以了解STL与其他语言的集合库之间的区别,并使其成为最佳集合库?

14 个答案:

答案 0 :(得分:26)

它不是那么“伟大”或“你可以用*任何*语言获得的最佳馆藏库”,但它确实与许多其他语言有不同的哲学。

特别是,标准C ++库使用泛型编程范例,而不是像Java和C#这样的语言中常见的面向对象的范例。也就是说,您对iterator应该是什么有一个“通用”定义,然后您可以实现带有的函数for_eachsortmax_element实现iterator模式的任何类,而不必实际从一些基本的“Iterator”接口或其他任何东西继承。

答案 1 :(得分:23)

STL有什么好处?

STL很棒,因为它很早就构思出来,但却成功地使用了C ++通用编程范例。

它有效地分离了数据结构:vectormap,...以及对它们进行操作的算法copytransform,...利用这样做的模板。

它巧妙地解决了问题,并为通用容器提供了自定义钩子(ComparatorAllocator模板参数)。

结果非常优雅(DRY原则),并且由于编译器优化非常有效,因此给定容器的手动生成算法不太可能做得更好。

这也意味着它易于扩展:您可以使用所需的接口创建自己的容器,只要它暴露符合STL的迭代器,您就可以使用STL算法!

由于使用了traits,你甚至可以通过普通指针在C-array上应用算法!谈论向后兼容性!

然而,它可能(或许)更好......

STL的优点是什么?

我真的很生气,我总是要使用迭代器,我真的代表能够写:std::foreach(myVector, [](int x) { return x+1;});因为面对它,大多数时候你想迭代整个容器...

但更糟糕的是因为:

set<int> mySet = /**/;

set<int>::const_iterator it = std::find(mySet.begin(), mySet.end(), 1005); // [1]
set<int>::const_iterator it = mySet.find(1005); // [2]

[1][2]执行完全不同,导致[1]具有O(n)复杂度,而[2]具有O(log n)复杂度!这里的问题是迭代器抽象得太多了。

我并不是说迭代器不值得,我只是说在迭代器方面提供接口接口是一个糟糕的选择。

我更喜欢自己对容器的观点的想法,例如,查看已对Boost.MPL做了什么。通过视图,您可以使用(惰性)转换层操纵容器。它使得非常有效的结构允许您过滤掉一些元素,转换其他元素等...

结合视图概念检查的想法,我认为会为STL算法生成更好的界面(并解决此问题find,{{1} },lower_boundupper_bound问题)。

它还可以避免使用错误定义的迭代器范围和由此产生的未定义行为的常见错误......

答案 2 :(得分:21)

我对STL的喜爱是多么强大。它很容易扩展。有些人抱怨它很小,缺少许多常见的算法或迭代器。但正是当你看到添加你需要的缺失组件是多么容易的时候。不仅如此,小而美:你有大约60种算法,少量容器和少量迭代器;但功能是这些产品的顺序。容器的接口仍然小而简单。

因为编写小巧,简单的模块化算法是时尚,所以更容易发现组件中的错误和漏洞。然而,与算法和迭代器一样简单,它们非常强大:您的算法将与许多现有的和尚未编写的迭代器一起工作,并且您的迭代器可以与许多现有的迭代器一起使用,而且还可以使用编写算法。

我也很喜欢STL的简单性。你有容器,你有迭代器,你有算法。就是这样(我躺在这里,但这是舒适的图书馆所需要的)。您可以将不同的算法与不同的迭代器混合使用不同的容器。确实,其中一些有限制禁止他们与他人合作,但总的来说有很多可以使用。

Niklaus Wirth说程序是算法加数据结构。这正是STL的意义所在。如果Ruby和Python是字符串超级英雄,那么C ++和STL就是算法和容器的超级英雄。

答案 3 :(得分:13)

STL的容器很不错,但它们与其他编程语言中的容器差别不大。使STL容器有用的原因是它们与算法完美地结合在一起。标准算法提供的灵活性在其他编程语言中是无与伦比的。

没有算法,容器就是这样。容器。没什么特别的。

现在,如果您只讨论C ++的容器库,那么您不太可能找到STL提供的库和测试库,如果没有别的,因为它们是标准的。

答案 4 :(得分:13)

STL与内置类型完美配合。 std::array<int, 5>就是这样 - 一个5 int的数组,在32位平台上消耗20个字节。

另一方面,

java.util.Arrays.asList(1, 2, 3, 4, 5)返回对包含对数组的引用的对象的引用,该数组包含对包含int s的Integer对象的引用。是的,这是3级间接,我不敢预测消耗多少字节;)

答案 5 :(得分:8)

这不是一个直接的答案,但是当你来自Java时,我想指出这一点。与Java等价物相比,STL 真的快。

我找到了this page,显示了一些性能比较。一般来说,Java人员在性能对话方面非常敏感,并且声称各种各样的进步一直在发生。然而,在C / C ++编译器中也出现了类似的进步。

答案 6 :(得分:7)

请记住,STL现在实际上已经很老了,所以其他更新的库可能具有特定的优势。鉴于年龄,它的受欢迎程度证明了原始设计有多好。

有四个主要原因让我说STL(仍然)很棒:

<强>速度 STL使用C ++模板,这意味着编译器会生成专门为您使用库而定制的代码。例如,map将自动生成一个新类,以实现'key'类型到'value'类型的map集合。没有运行时开销,库试图找出如何有效地存储'key'和'value' - 这是在编译时完成的。由于优雅的设计,某些类型的某些操作将编译为单个汇编指令(例如,增加基于整数的迭代器)。

<强>效率 集合类有一个“分配器”的概念,您可以自己提供,也可以使用库提供的分配器,它们只分配足够的存储空间来存储数据。没有填充物也没有浪费。在可以更有效地存储内置类型的情况下,存在可以最佳地处理这些情况的专门化,例如, bool的矢量作为一个位域处理。

<强> Exensibility 您可以在任何适合的类型中使用STL中提供的Containers(集合类),算法和函数。如果可以比较您的类型,可以将其放入容器中。如果它进入容器,可以对其进行排序,搜索和比较。如果你提供像'bool Predicate(MyType)'这样的函数,它可以被过滤等等。

<强>雅 其他库/框架必须在每种类型的集合上实现Sort()/ Find()/ Reverse()方法。 STL将这些作为单独的算法实现,它们使用的任何集合的迭代器并盲目地对该集合进行操作。算法并不关心你是使用Vector,List,Deque,Stack,Bag,Map - 它们只是起作用。

答案 7 :(得分:3)

嗯,这有点大胆的说法......也许在C ++ 0x中,当它最终得到一个哈希映射(以std :: unordered_map的形式)时,它可以做出声明,但是在当前状态下好吧,我不买。

但是,我可以告诉你一些很酷的事情,即它使用模板而不是继承来实现其灵活性和通用性。这有利有弊;缺点是编译器会复制大量代码,并且很难实现任何类型的动态运行时类型;然而,一个关键的优势是它非常快。因为每个模板特化实际上都是由编译器生成的独立类,所以它可以针对该类进行高度优化。此外,许多在STL容器上运行的STL算法都有一般定义,但对特殊情况有专门化,可以产生非常好的性能。

答案 8 :(得分:3)

STL为您提供了各种作品。

语言及其环境是通过较小的组件构建的,有时通过编程语言构造,有时通过剪切和粘贴。有些语言会给你一个密封的盒子 - 例如Java的集合。你可以做他们允许的事情,但如果你想做一些与他们不同的事情,你会感到懊恼。

STL为您提供设计师用于构建其更高级功能的部分。直接暴露迭代器,算法等,为您提供了一种抽象但高度灵活的方式,以适合解决问题的方式重新组合核心数据结构和操作。虽然Java的设计可能会从数据结构中达到90-95%的标记,但STL的灵活性可能会提高到99%,而迭代器抽象意味着你不能完全依靠自己的剩余1%。

当您将其与其速度和其他可扩展性以及自定义功能(分配器,特性等)结合使用时,您就拥有了非常出色的包。我不知道我称之为最好的数据结构包,但肯定是非常好的。

警告:百分比完全弥补。

答案 9 :(得分:2)

独特,因为它

  • 专注于基本算法,而不是为特定应用程序问题提供现成的解决方案。
  • 使用独特的C ++功能来实现这些算法。

至于最好......有一个原因是为什么同样的方法不会(也可能不会)跟随任何其他语言,包括像D这样的直接后代。

答案 10 :(得分:2)

标准C ++库通过迭代器收集的方法最近引起了一些建设性的批评。着名的C ++专家Andrei Alexandrescu最近开始研究一种名为D和describes his experiences designing collections support for it in this article的语言的新版本。

我个人觉得这种优秀的作品被用于另一种与现有语言重叠的编程语言,并且我已经告诉过他了,这让我很失望! :)我希望他的专业知识能够转向为所谓的“现代语言”创建一个集合库,这些库已经广泛使用,Java和C#,具有他认为需要的所有功能。世界级:前向可迭代范围的概念已经无处不在,但是以有效的方式暴露出反向迭代呢?可变集合怎么样?如何将这一切顺利地与Linq整合?等

无论如何,重点是:不要相信任何告诉你标准C ++方式是圣杯的人,这是最好的。它只是众多方法中的一种,并且至少有一个明显的缺点:在所有标准算法中,集合由两个独立的迭代器(开始和结束)指定,因此组合操作很笨拙。

答案 11 :(得分:2)

显然,C ++,C#和Java可以根据需要输入尽可能多的小便竞赛。关于为什么STL至少有点好用的线索是Java最初是在没有类型安全容器的情况下设计和实现的。然后,Sun决定/意识到人们实际上需要一种打字语言,并在1.5中添加了泛型。

你可以比较每种语言的优缺点,但是这三种语言中哪一种具有通用容器的“最佳”实现 - 这只是一种小便竞赛。最重要的是什么?在谁看来?他们每个人都拥有创作者设法提出的最好的图书馆,受到语言强加的其他限制。 C ++关于泛型的思想在Java中不起作用,并且类型擦除在典型的C ++用法中将是不合标准的。

答案 12 :(得分:0)

首要的是,您可以使用模板来使用容器切换/切换,而不必诉诸Java界面的可怕混乱。

答案 13 :(得分:0)

如果你没看到STL有什么用处,我建议买一本书,Bjarne Stroustrup的“The C ++ Programming Language”。它几乎解释了有关C ++的所有内容,因为他是创建它的人。