JavaScript is required to for searching.
跳过导航链接
退出打印视图
Oracle Solaris Studio 12.3:C++ 用户指南     Oracle Solaris Studio 12.3 Information Library (简体中文)
search filter icon
search icon

文档信息

前言

第 1 部分C++ 编译器

1.  C++ 编译器

2.  使用 C++ 编译器

3.  使用 C++ 编译器选项

第 2 部分编写 C++ 程序

4.  语言扩展

5.  程序组织

6.  创建和使用模板

7.  编译模板

7.1 详细编译

7.2 系统信息库管理

7.2.1 生成的实例

7.2.2 整个类实例化

7.2.3 编译时实例化

7.2.4 模板实例的放置和链接

7.3 外部实例

7.3.1 可能的高速缓存冲突

7.3.2 静态实例

7.3.3 全局实例

7.3.4 显式实例

7.3.5 半显式实例

7.4 模板系统信息库

7.4.1 系统信息库结构

7.4.2 写入模板系统信息库

7.4.3 从多模板系统信息库读取

7.4.4 共享模板系统信息库

7.4.5 通过 -instances=extern 实现模板实例自动一致

7.5 模板定义搜索

7.5.1 源文件位置约定

7.5.2 定义搜索路径

7.5.3 诊断有问题的搜索

8.  异常处理

9.  改善程序性能

10.  生成多线程程序

第 3 部分库

11.  使用库

12.  使用 C++ 标准库

13.  使用传统 iostream

14.  生成库

第 4 部分附录

A.  C++ 编译器选项

B.  Pragma

词汇表

索引

7.3 外部实例

对于外部实例方法,所有实例都放置在模板系统信息库中。编译器确保只有一个一致的模板实例存在;这些实例既不是未定义的也不是多重定义的。模板仅在需要时才重新实例化。对于非调试代码,所有目标文件(包括模板缓存中的任何目标文件)在使用 -instances=extern 时的大小总量可能会小于在使用 -instances=global 时的大小总量。

模板实例接受系统信息库中的全局链接实例是使用外部链接从当前编译单元引用的。


注 - 如果在不同的步骤中进行编译和链接,并且在编译步骤中指定了 -instance=extern,则还必须在链接步骤中指定该选项。


这种方法的缺点是每当您更改程序或进行重大程序更改时都必须清除高速缓存。高速缓存是并行编译的瓶颈,这与使用 dmake 时一样,因为每次只能有一个编译访问高速缓存。另外,您只能在每个目录内生成一个程序。

与在主目标文件中直接创建有效模板实例并在以后丢弃该实例(如果需要)相比,确定某个有效实例是否已在高速缓存中可能需要更长的时间。

使用 -instances=extern 选项指定外部链接。

因为实例存储在模板系统信息库中,所以必须使用 CC 命令将使用外部实例的 C++ 对象链接到程序中。

如果要创建包含了使用的所有模板实例的库,请使用 -xar 选项进行编译。而要使用 ar 命令。例如:

example% CC -xar -instances=extern -o libmain.a a.o b.o c.o

7.3.1 可能的高速缓存冲突

如果指定了 -instance=extern,请勿在同一目录中运行不同的编译器版本,以避免可能的高速缓存冲突。使用 -instances=extern 模板模型进行编译时,请注意以下事项:

7.3.2 静态实例


注 - -instances=static 选项已过时,因为 -instances=global 现在提供了 static 的所有优点,并克服了其缺点。早期的编译器中提供了此选项来克服现已不存在的问题。


对于静态实例方法,所有实例都被放置在当前编译单元内。因此,模板在每个重新编译期间重新实例化;这些实例不保存到模板系统信息库。

这种方法的缺点是不遵循语言语义,并且会生成很大的对象和可执行文件。

实例接收静态链接。这些实例在当前编译单元外部是不可视的或不可用的。因此,模板可以在多个目标文件中具有相同的实例化。因为多重实例产生了不必要的大程序,所以对于不可能多重实例化模板的小程序可以使用静态实例链接。

静态实例的编译速度很快,因此这种方法也适用于修复并继续方式的调试。(请参见《使用 dbx 调试程序》。)


注 - 如果您的程序取决于多个编译单元间的共享模板实例(例如模板类或模板函数的静态数据成员),请勿使用静态实例方法。否则程序会工作不正常。


可使用 -instances=static 编译器选项指定静态实例链接。

7.3.3 全局实例

与早期的编译器发行版不同,现在不必预防出现一个全局实例有多个副本的情况。

这种方法的优点是通常由其他编译器接受的不正确源代码也能在这种模式中接受。需要特别指出的是,从模板实例内对静态变量的引用是不合法的,但通常是可以接受的。

这种方法的缺点是单个目标文件可能会较大,因为可能会在多个文件中存在模板实例的多个副本。如果编译目标文件以便进行调试时,有些使用了 -g 选项,而有些没有使用该选项,则很难预测是获得链接到程序中模板实例的调试版本还是非调试版本。

模板实例接收全局链接。这些实例在当前编译单元外部是可视的和可用的。

可使用 -instances=global 选项(缺省值)指定全局实例。

7.3.4 显式实例

在显式实例方法中,仅为显式实例化的模板生成实例。隐式实例化不能满足该要求。实例被放置在当前编译单元内。

这种方法的优点是拥有最少的模板编译和最小的对象大小。

缺点是您必须手动执行所有的实例化。

模板实例接收全局链接。这些实例在当前编译单元外部是可视的和可用的。链接程序识别并丢弃重复项目。

可使用 -instances=explicit 选项指定显式实例。

7.3.5 半显式实例

使用半显式实例方法时,仅为显式实例化或模板体内隐式实例化的模板生成实例。显式创建的实例所必需的实例将自动生成。主线代码中隐式实例化不满足该要求。实例被放置在当前编译单元内。因此,模板在每个重新编译期间重新实例化;生成的实例接收全局链接,且不会被保存到模板系统信息库中。

可使用 -instances=semiexplicit 选项指定半显式实例。