什么时候模板实例化膨胀在实践中很重要?

dsi*_*cha 12 c++ templates d

似乎在C++和D中,静态编译的语言和模板元编程是一种流行的技术,对模板实例化膨胀有很多关注.除了资源非常有限的嵌入式系统外,在我看来,这似乎主要是理论上的问题.在嵌入式领域之外,我还没有听说过一个人能够证明这在实践中是一个问题的例子.

任何人都可以在资源有限的嵌入式系统之外提供一个例子,其中模板实例化膨胀在实践中很重要并且具有可测量的,实际上显着的负面影响吗?

Fee*_*ure 10

C++中没有什么问题,因为你在C++中可以做的模板内容的数量受到复杂性的限制.

但是在D中......在CTFE(编译时功能评估)存在之前,我们不得不使用模板进行字符串处理.这也是在DMD中压缩大错位符号的原因 - 用作模板参数的字符串成为错位符号名称的一部分,并且当实例化具有较长代码段的模板时(例如),得到的符号大小将极大地爆炸对象格式.

现在好多了.但总的来说,模板仍然会因为一个简单的原因而导致很多膨胀 - 它们解析得比C++更快,更强大,因此人们自然会使用它们更多(即使在技术上不需要模板的情况下).我必须承认我是这里的主要违规者之一(如果你愿意,可以看一下tools.base,但一定要保留一个方便的barf包 - 该文件实际上是90%的模板代码).


Mar*_*ork 7

模板膨胀不是问题(这是一个心理问题,而不是代码问题).

是的它可以变大.但是替代方案是什么?
您可以手动编写所有代码(每种类型一次).你认为手动编写它会使它变小.编译器仅实例化它实际需要的版本,链接器将删除分布在编译单元上的多个副本.

所以没有实际的膨胀.
它只是在构建你使用的东西.如果您使用许多不同类型,则需要编写更多代码.

  • 如果您只是将模板用作泛型,那么情况就是如此.但是,如果使用模板进行元编程,则不然.元编程中使用的模板可以实例化您并不真正需要的各种疯狂的中间类型.我认为boost :: spirit解析器生成器可能是一个很好的例子. (3认同)
  • 这不完全正确 - 编译器可能为不同的函数`f <signed int>(signed int)`和`f <unsigned int>(unsigned int)`生成相同的代码,并且可能不会注意到它们是相同的.而手动编写它只会获得其中一个功能. (2认同)
  • 理想情况下,您应该使用识别并删除重复生成的汇编代码的编译器/链接器.Visual Studio执行此操作(COMDAT折叠). (2认同)