使用模板有哪些缺点?

时间:2010-04-29 05:37:50

标签: c++ templates generic-programming

一些缺点是

  1. 其语法很复杂
  2. 编译器生成额外代码

11 个答案:

答案 0 :(得分:24)

他们很难验证。没有使用的模板代码往往很少被编译。因此,必须对测试用例进行良好的覆盖。但是测试是耗时的,然后它可能会导致代码永远不需要强大的代码。

答案 1 :(得分:22)

嗯,怎么样......

3:编译速度慢

4:它们强制在编译时计算事物而不是运行时间(如果您更喜欢快速执行速度而不是运行时灵活性,这也是一个优势)

5:较旧的C ++编译器无法处理它们,或者无法正确处理它们

6:当你没有得到正确的代码时,它们产生的错误消息几乎是不可理解的

答案 2 :(得分:12)

模板将您的实现暴露给代码的客户端,如果您在库边界传递模板化对象,这将使您的ABI更难维护。

答案 3 :(得分:10)

唯一真正的缺点是,如果你在模板中做出任何微小的语法错误(尤其是其他模板使用的错误)错误消息会有所帮助...期待几页几乎无法使用的错误信息;-)。编译器的缺陷是特定于编译器的,而语法虽然丑陋但并不真正“复杂”。总而言之 - 尽管有适当的错误诊断存在巨大问题 - 模板仍然是 关于C ++的最好的事情,但有一点可能诱使你使用C ++而不是其他语言泛型的实现,例如Java ......

答案 4 :(得分:10)

到目前为止,似乎没有人提到我使用模板找到的主要缺点:代码可读性严重下降!

我不是指语法问题 - 是的,语法很难看,但我可以原谅。我的意思是这样的:我发现从未见过的非模板化代码,无论应用程序多么大,如果我从main()开始,我通常可以解码程序正在做的广泛的行程而没有问题。仅使用vector<int>或类似的代码并不会让我感到烦恼。但是,一旦代码开始为简单的容器类型之外的目的定义和使用自己的模板,可理解性就会迅速消失。 这对代码维护有非常不利的影响。

部分原因是不可避免的:模板通过复杂的偏序重载决策规则(对于函数模板)提供更大的表现力,并且在较小程度上提供部分特化(对于类模板)。但规则是如此复杂甚至编译器编写者(我很高兴地承认他比我更聪明一个数量级)在极端情况下仍然是错误的。

C ++中命名空间,朋友,继承,重载,自动转换和依赖于参数的查找的交互已经足够复杂了。但是当你在混合中添加模板时,以及它们带来的名称查找和自动转换规则的细微变化,复杂性可以达到我认为没有人可以处理的比例。我只是不相信自己阅读和理解使用所有这些结构的代码。


与模板无关的困难是调试器仍然难以自然地显示STL容器的内容(与C风格的数组相比)。

答案 5 :(得分:4)

编译器解析它们很复杂,这意味着编译时间会增加。如果您有高级模板结构,也很难解析编译器错误消息。

答案 6 :(得分:3)

人们很少理解它们,特别是在元编程层面,因此人们可以维护它们。

答案 7 :(得分:1)

使用模板时,编译器只生成您实际使用的内容。我认为使用C ++模板元编程没有任何缺点,除非你使用非常复杂的结构作为boost或loki库,编译时间可能会很长。

答案 8 :(得分:1)

缺点:模板错误仅在实例化模板时由编译器检测到。有时,只有在实例化成员方法时才会检测模板方法中的错误,无论模板的其余部分是否已实例化。

如果模板类的方法中有错误,只有一个函数引用,但是其他代码使用没有该方法的模板,则编译器在实例化错误方法之前不会生成错误。

答案 9 :(得分:1)

绝对最差:从错误的模板代码中获得的编译器错误消息。

答案 10 :(得分:0)

多年来我有时会使用模板。它们可以派上用场,但从专业角度来看,我偏离它们。其中两个原因是:

1

需要a。)将函数定义(不仅是声明)“source”代码暴露给“where used”代码或b。)在源文件中创建虚拟实例化。这是编译所必需的。选项a。)可以通过在标题中定义函数或实际包含cpp。

来完成

我们在C ++中容忍标头的原因之一(例如与C#相比)是因为“接口”与“实现”的分离。好吧,模板似乎与这种理念不一致。

2

模板类型参数实例化调用的函数可能无法在编译时强制执行,从而导致链接错误。例如。例子; example.CompilerDoesntKnowIfThisFunctionExistsOnT(); 这是“松散的”恕我直言。

解决方案:

而不是模板,我倾向于使用基类,派生/容器类知道编译时可用的内容。基类可以提供模板经常用于的通用方法和“类型”。这就是为什么如果需要修改现有代码以在需要的继承层次结构中插入通用基类,源代码可用性会很有用。否则,如果代码是闭源代码,则使用通用基类更好地重写代码,而不是使用模板作为解决方法。

如果类型不重要,例如矢量&lt; T>然后如何使用“对象”。 C ++没有提供“对象”关键字,我已经向Bjarne Stroustrup博士提出,这对于告诉编译器和人们阅读类型不重要的代码(对于不是这样的情况)会有所帮助。我不认为C ++ 11有这个,也许C ++ 14会吗?