使用 C++ 模板

在 C++ 中,可以使用模板来声明一组相关的:
  • 类 (包括结构)
  • 函数
  • 模板类的静态数据成员

减少冗余模板实例化

在应用程序中,可以使用相同自变量或不同自变量多次实例化同一模板。 如果使用相同的自变量 用于不同编译单元中的模板实例化,那么重复实例化是冗余的。 这些冗余实例会增加编译时间,增加可执行文件的大小,并且不会带来任何益处。

对于冗余实例化问题,有几种基本方法:

在链接期间处理冗余
最终可执行文件的大小增加可能很小,以至于无法改变编译程序或修改源文件的方式。 大多数临客都有某种形式的垃圾回收功能。 AIX®上,链接程序很好地执行垃圾回收,尤其是在使用 -qfuncsect 选项时。 基于 XL 的前端开始如果您使用 -qtmplinst=always-qtmplinst=auto ,而没有使用 -qtemplateregistry-qtempinc ,则不会进行冗余实例的编译时间管理。基于 XL 的前端端 在这种情况下,您可以使用 -qfuncsect 选项来减小可执行文件的大小。 有关详细信息,请参阅 XL C/C++ Compiler Reference中的 -qfuncsect
控制源代码中的隐式实例化
集中特定化的隐式实例化: 组织源代码,以便对象文件包含更少的每个必需实例化实例和更少的未使用实例化实例。 这是最不可用的方法,因为您必须知道在何处定义了每个模板,使用了哪些实例化以及在何处为每个实例化声明显式实例化。
C++11使用显式实例化声明: 使用显式实例化声明功能,您可以抑制模板特化或其成员的隐式实例化。 这有助于减少对象文件的集合体大小。 如果禁止的符号定义意在共享库中找到,或者如果系统链接程序无法始终除去符号的其他定义,那么它还可能会减小最终可执行文件的大小。 更多信息,请参阅使用显式实例化声明( C++11C++11
注意 :如果您想在源代码中控制隐式实例化,或者使用显式实例化声明,可以使用 -qtmplinst=none基于 XL 的前端开始-qtmplinst=noinlines基于 XL 的前端端 选项来防止意外发生隐式实例化。
基于 XL 的前端开始让编译器将实例化信息存储在注册表中
使用 -qtemplateregistry 编译器选项。 有关每个模板实例化的信息存储在模板注册表中。 如果要求编译器使用相同的自变量再次实例化同一模板,那么它将指向第一个对象文件中的实例化。 此方法在 使用-qtemplatereg化学编译器选项中进行了描述。
基于 XL 的前端开始让编译器将实例存储在模板的include目录中
使用 -qtempinc 编译器选项。 如果模板定义和实现文件具有必需的结构,那么每个模板实例化都存储在模板包含目录中。 如果要求编译器使用相同的自变量再次实例化同一模板,那么它将改为使用存储的版本。 在模板 include 目录中创建的源文件将在链接步骤期间以递归方式进行编译,直到完成所有实例化为止。 使用 -qtempinc 编译器选项中描述了此方法。
注: 仅将此方法用于旧代码。
基于 XL 的前端开始
备注信息:
  • -qtempinc-qtemplateregistry 编译器选项互斥。
  • 由于以下原因, -qtemplateregistry 是比 -qtempinc 更好的方法:
    • -qtemplateregistry 提供比 -qtempinc更好的优势。
    • -qtemplateregistry 不需要修改头文件。
基于 XL 的前端端
除非满足下列其中一个条件,否则编译器将为隐式实例化生成代码:
  • 您可以使用 -qtmplinst=none 基于 XL 的前端开始-qtmplinst=noinlines基于 XL 的前端端
  • 基于 XL 的前端开始您使用的是 -qtmplinst=auto ,这是 -qtmplinst-qnotemplateregistry 的默认子选项。
  • 基于 XL 的前端开始您使用 -qtmplinst=auto-qtempinc ,模板源代码组织起来使用 -qtempinc
  • C++11当前翻译单元中存在该实例化的显式实例化声明。C++11