在相关问题中,Why can templates only be implemented in the header file? ,描述了两种避免链接器错误的策略:
- 在头文件中实现整个模板;或者
- 使用
template class Foo<int>
显式实例化模板语法。
据我所知,#1 似乎是“首选”方法,并在每个图书馆中使用 - 大概是因为很难或不可能预测图书馆消费者想要使用哪些类型。我的问题涉及策略 #2。
具体来说,我为什么要这样做?
仅供引用:我大多是 C++ 的新手,具有很深的 C# 背景。我习惯了 .NET 风格的泛型,它更直接一些,是的,我理解为什么它们是不同的。但是,我认为 C++ 开发人员仍然关心耦合。形式 #2 是否引入了一种特别烦人的耦合形式,其中开发人员必须不断编辑模板的 .cpp 文件才能使用具有不同的、以前无法预料的类型的模板?这不是违背了模板的目的吗?
是否存在与解决方案 #2 相关的合法或重要用例?
最佳答案
在 header 中实现整个模板有明显的优势(首选方法):
- 添加模板特化:许多标准库模板可能是特化的。
- 在新类型上使用它:模板是为了通用性,如果您不能随心所欲地选择模板参数,它就会受到很大限制。
- 学习其他模板专业。
那么,为什么要在实现文件中使用显式模板实例化,而只在头文件中提供模板的接口(interface)呢? (纯粹的方法根本没有真正用过)
- 实现隐藏。
- 更快的编译!!由于大量使用模板,否则我们会遇到一个经典的O(n*m) 问题。
- 将这些模板放在共享库中以减少代码大小。
还有一种混合方法,它试图在保留第一种方法的所有优点的同时获得第二种方法的一些优点:
使用 extern
定义最常用的模板实例化,并提供来自共享库的显式实例化。
这具有第一种方法的所有优点,但只有第二种方法的一个优点:
这些显式实例化可以在共享库中。
共享 C++ 语言库使用这种混合方法。
顺便说一句:委员会对目前的事态不满意:
他们正在开发一个真正的模块系统,它将结合两者的优点。
这个 SO 帖子有一些信息:C++ Modules - why were they removed from C++0x? Will they be back later on?
2014 年 5 月的 C++ 委员会提案:A Module System for C++
关于c++ - 什么时候显式实例化模板是合适的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25005905/