引用 C++ 标准库:教程和手册:
目前使用模板的唯一可移植方式是通过使用内联函数在头文件中实现它们。
为什么是这样?
(澄清:头文件不是 唯一 的可移植解决方案。但它们是最方便的可移植解决方案。)
原文由 MainID 发布,翻译遵循 CC BY-SA 4.0 许可协议
引用 C++ 标准库:教程和手册:
目前使用模板的唯一可移植方式是通过使用内联函数在头文件中实现它们。
为什么是这样?
(澄清:头文件不是 唯一 的可移植解决方案。但它们是最方便的可移植解决方案。)
原文由 MainID 发布,翻译遵循 CC BY-SA 4.0 许可协议
我建议查看这个 gcc 页面,该页面讨论了模板实例化的“cfront”和“borland”模型之间的权衡。
https://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/Template-Instantiation.html
“borland”模型对应于作者的建议,提供完整的模板定义,并多次编译。
它包含有关使用手动和自动模板实例化的明确建议。例如,“-repo”选项可用于收集需要实例化的模板。或者另一种选择是使用“-fno-implicit-templates”禁用自动模板实例化以强制手动模板实例化。
根据我的经验,我依赖于为每个编译单元实例化的 C++ 标准库和 Boost 模板(使用模板库)。对于我的大型模板类,我会为我需要的类型进行一次手动模板实例化。
这是我的方法,因为我提供的是工作程序,而不是用于其他程序的模板库。这本书的作者 Josuttis 在模板库方面做了很多工作。
如果我真的担心速度,我想我会探索使用预编译头 https://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html
这在许多编译器中获得了支持。但是,我认为模板头文件很难预编译头文件。
原文由 Juan 发布,翻译遵循 CC BY-SA 4.0 许可协议
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
1 回答2.7k 阅读✓ 已解决
3 回答3.4k 阅读
1 回答1.6k 阅读✓ 已解决
警告: 没有 必要将实现放在头文件中,请参阅此答案末尾的替代解决方案。
无论如何,您的代码失败的原因是,在实例化模板时,编译器会使用给定的模板参数创建一个新类。例如:
阅读此行时,编译器会创建一个新类(我们称之为
FooInt
),相当于如下:因此,编译器需要访问方法的实现,以使用模板参数实例化它们(在本例中为
int
)。如果这些实现不在标头中,它们将无法访问,因此编译器将无法实例化模板。一个常见的解决方案是在头文件中编写模板声明,然后在实现文件(例如 .tpp)中实现类,并在头文件的末尾包含这个实现文件。
Foo.h
文件.tpp
这样,实现仍然与声明分离,但编译器可以访问。
替代解决方案
另一种解决方案是保持实现分离,并显式实例化您需要的所有模板实例:
Foo.h
Foo.cpp
如果我的解释不够清楚,您可以查看 有关此主题的 C++ Super-FAQ 。