模板,仅在 header 文件中编码?
Templates, coding only in header file?
最近我了解到,如果我想使用模板,我应该只在 header files.I 中实现代码,知道在 .h 和 .cpp 文件中有解决方案,但假设我不想那样做,我应该把我所有的代码都写在 .h 文件中吗?这是编写代码的好方法吗,即使程序可能很大?此外,只有.h文件(不包括main函数)而从不使用.cpp文件看起来很奇怪。
将声明和接口文档与实现分开 就像您通常对 header (*.h
) 和源文件 (*.cpp
) 由于 C++ 编译过程,通常 无法使用模板 。
在编译过程中,所有 header 文件只是包含到调用它们的源文件中,然后独立处理这些源文件,最后将所有生成的 object 文件链接到一起一个可执行文件。模板是通用 data-types 的函数,它们仅针对调用它们的 data-types 进行实例化。这意味着模板函数不会创建任何代码,只要它没有被具有有效模板参数的人实例化。您必须以某种方式确保使用访问模板函数的所有源文件所需的数据类型实例化模板。
- 如果您将声明放在 header 文件中,将实现放在源文件中(就像您通常对函数所做的那样),只有那些在该特定源文件中已知的版本才会被实例化。这意味着任何其他需要一组不同参数的源文件都可能导致链接器错误,因为它不知道源文件没有包含模板参数的正确组合,这使得它不可移植。
- 您可以 instantiate all the required versions manually 减少开销,但通常这会使您失去很多灵活性,因为您必须事先定义哪些模板参数将用于其他翻译单元。
- 最后,您可以简单地将 声明和实现留在 header 文件 中。这会减慢编译过程,因为 header 的所有内容都必须粘贴到调用它的所有源文件中。因此,有些人不喜欢 Boost but it gives you the most flexibility. This effect can though be reduced by features like pre-compiled headers. In order to make this more easily readable again some libraries separate declaration (and documentation) from the implementation by putting the declaration in
*.h
files and define the implementation in *.hpp
-files (similar to * .cpp
, see here). 等大量模板化的库。
所以通常这取决于用法:如果您知道特定的模板函数仅在特定的源文件中使用,您可以将文档、声明和实现放入源文件(而不是 header ).如果您想与多个源文件共享模板函数,请将声明和实现放在 header 中。这通常是标准方式,因为它最灵活。如果您编写一个完全模板化的库,那么可能在 *.h
文件中分离声明和文档,在 *.hpp
文件中分离实现可能是最有意义的,但主要只是为了有一个更简单的概述。无论如何,某些函数的声明和实现之间没有明确的分离是完全正常的,因此某些 header 文件可能缺少相应的源文件。
最近我了解到,如果我想使用模板,我应该只在 header files.I 中实现代码,知道在 .h 和 .cpp 文件中有解决方案,但假设我不想那样做,我应该把我所有的代码都写在 .h 文件中吗?这是编写代码的好方法吗,即使程序可能很大?此外,只有.h文件(不包括main函数)而从不使用.cpp文件看起来很奇怪。
将声明和接口文档与实现分开 就像您通常对 header (*.h
) 和源文件 (*.cpp
) 由于 C++ 编译过程,通常 无法使用模板 。
在编译过程中,所有 header 文件只是包含到调用它们的源文件中,然后独立处理这些源文件,最后将所有生成的 object 文件链接到一起一个可执行文件。模板是通用 data-types 的函数,它们仅针对调用它们的 data-types 进行实例化。这意味着模板函数不会创建任何代码,只要它没有被具有有效模板参数的人实例化。您必须以某种方式确保使用访问模板函数的所有源文件所需的数据类型实例化模板。
- 如果您将声明放在 header 文件中,将实现放在源文件中(就像您通常对函数所做的那样),只有那些在该特定源文件中已知的版本才会被实例化。这意味着任何其他需要一组不同参数的源文件都可能导致链接器错误,因为它不知道源文件没有包含模板参数的正确组合,这使得它不可移植。
- 您可以 instantiate all the required versions manually 减少开销,但通常这会使您失去很多灵活性,因为您必须事先定义哪些模板参数将用于其他翻译单元。
- 最后,您可以简单地将 声明和实现留在 header 文件 中。这会减慢编译过程,因为 header 的所有内容都必须粘贴到调用它的所有源文件中。因此,有些人不喜欢 Boost but it gives you the most flexibility. This effect can though be reduced by features like pre-compiled headers. In order to make this more easily readable again some libraries separate declaration (and documentation) from the implementation by putting the declaration in
*.h
files and define the implementation in*.hpp
-files (similar to* .cpp
, see here). 等大量模板化的库。
所以通常这取决于用法:如果您知道特定的模板函数仅在特定的源文件中使用,您可以将文档、声明和实现放入源文件(而不是 header ).如果您想与多个源文件共享模板函数,请将声明和实现放在 header 中。这通常是标准方式,因为它最灵活。如果您编写一个完全模板化的库,那么可能在 *.h
文件中分离声明和文档,在 *.hpp
文件中分离实现可能是最有意义的,但主要只是为了有一个更简单的概述。无论如何,某些函数的声明和实现之间没有明确的分离是完全正常的,因此某些 header 文件可能缺少相应的源文件。