【发布时间】:2010-09-20 23:01:15
【问题描述】:
使用 STL 或模板有什么缺点吗?是否有不适合的情况。
【问题讨论】:
使用 STL 或模板有什么缺点吗?是否有不适合的情况。
【问题讨论】:
首先,如果它们可以帮助您解决问题,您应该使用可能使用它们。模板是 C++ 中非常重要的一部分,并且多年来一直是标准的一部分。 STL 在运行时非常强大且速度很快,应该得到所有体面的编译器的支持,但当然也存在一些问题。
仅举几例,但不使用它们的缺点可能要大得多。
【讨论】:
明显的缺点:
语法可能很糟糕 - C++ 中的一些模板语法确实突破了理智的极限,并与语言的其他部分重叠(例如 >>)
很多人不太了解 STL,因此您可能会限制您的受众。
错误消息往往非常复杂。
STL 集合的设计往往会导致大量的对象复制。最初的“智能指针”(std::auto_ptr)不适合在大多数集合中使用。最近这方面的情况有所改善(TR1)
【讨论】:
有几个潜在的好处和缺点
话虽如此,我们使用 C++ 和模板(在某些领域还使用元编程技术)来为我们的整体代码库带来好处。代码比没有模板时的代码略大,但性能和可维护性的权衡大于大小。我们确实有熟练/经验丰富的 C++ 程序员致力于开发和维护代码。
如果您使用缺点来决定是否使用 C++ 功能/库 - 请确保您同样权衡语言的好处以及您的项目/产品/公司愿意权衡的好处。希望这会有所帮助。
编辑:我忘记提及的另一个主要缺点 - 便携性。如果您需要编写可移植的代码,模板可能不是正确的方法。当今大多数流行的编译器都支持 STL,但大多数并不是全部。元编程技术可能是可移植性的真正杀手,因此这是决定其使用适当性的明确考虑因素。
【讨论】:
用于嵌入式设备编程(在我的例子中——智能手机)。由于担心生成的代码大小(少量 RAM 和磁盘空间),不鼓励使用模板。此外,编译器非常古老,可能无法处理一些与模板相关的构造。
【讨论】:
大量模板滥用(尤其是 模板元编程和Boost 成瘾)会导致过度 编译和链接时间长。
您还可以使用可执行文件 有相当大的 (未剥离的)二进制文件,但通常 这不是一个可怕的问题。
设计不佳的模板也可以 进一步增加代码重复 加剧可执行文件大小 问题。
对于具有大 实现还需要 考虑这样一个事实,即使用 他们的模板意味着移动 整个类体变成一个标题 某处。这地方多了很多 如果模板加载链接器 在多个地方使用。
来自大量模板化代码的错误消息可能会让外行人望而生畏,而且很少能像从非模板化代码中得到的错误消息那样清晰。
也就是说,对于大多数应用程序来说,模板是代码重用的绝佳工具,有助于提升从重新实现到重用代码的讨论水平;这些问题很少能胜过好处。
【讨论】:
套用现代 C++ 设计名声的 Andrei Alexandrescu 的话。 Template are an orthogonal structure to multiple inheritance。它们都有互补的权衡和好处。模板具有丰富的机制,但模板的专业化无法扩展。
【讨论】:
模板的目标是以最小的性能损失提供抽象。在大多数情况下,利大于弊。模板的大部分问题来自编译器和调试器的支持。
我对模板的不满:由于标头依赖性,它击败了智能构建系统。与开发纯面向对象的系统相比,开发模板代码往往会导致更多的未修改代码的重新编译,尤其是如果后者很好地使用了 DIP(依赖倒置原则)。这加剧了慢编译问题。 OTOH,如今更快的开发硬件使事情比以前更容易忍受。
对于 STL(以及 Boost),他们的目标是提供可移植且合理高效的数据结构和算法。对于某些性能关键的应用程序,它们不一定是最佳选择。例如:虽然hash_map (tr1/unordered_map) 在一般情况下表现得相当好,但特殊用途的哈希表(例如,google 稀疏/密集哈希表库)在内存使用或速度方面可以大大优于通用 STL 实现。
【讨论】:
有很多支持和反对 C++ 模板的哲学(充其量)论据,但我倾向于接受最多的一个是在编译时实例化它们的机制会产生大量的代码膨胀。
虽然这通常不是什么大问题,但当您为二进制大小限制非常有限的嵌入式系统编写代码时,它会产生重大影响。
【讨论】:
在 MSVC 实现中,std::string 每个字符串有 26 个字节的开销,即使字符串为空。如果您只使用 char*,则每个字符串将是 4 个字节。
【讨论】:
复杂的 STL 容器(以及任何复杂的 C++ 类)使调试变得更加困难。
除了前面提到的不可读的错误消息之外,当前的调试器通常很少支持处理 STL 结构。例如,在运行时检查原生 C 数组比 vector 容器容易得多。
希望情况会随着时间而改变。 除此之外,模板很棒。
【讨论】:
其中一个原因可能是它们很难翻译成其他不支持模板的面向对象语言,例如 C# 和 Java,因此如果您有来自这些语言的开发人员组,他们将面临更陡峭的学习曲线。
【讨论】:
模板实例化的方式要求您在跨翻译单元共享模板时注意如何声明和定义模板。 “C++ 模板:完整指南”一书是有关如何处理此问题的良好信息来源。
模板的编译器和链接器错误消息往往非常非常冗长。你必须习惯这一点,我认为有一些脚本/工具可以让它们更具可读性,但我对它们没有任何经验。
但除此之外,模板也很棒!
【讨论】:
请参阅 C++ FQA [原文如此] 中的 templates section,了解不使用模板的许多充分理由。
【讨论】: