Sun Studio 12 Update 1:C++ 用户指南

7.3 外部实例

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

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


注 –

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


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

决定缓存中是否存在有效的模板实例比直接在主目标文件中创建实例(如果需要,用完后可以丢弃)要花费更长的时间。

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

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

如果要创建包含了使用的所有模板实例的库,请结合使用 CC 命令与 — xar 选项。而要使用 ar 命令。例如:


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

有关更多信息,请参见表 15–3

7.3.1 可能的缓存冲突

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

7.3.2 静态实例


注 –

-instances=static 选项已过时。没有任何理由再使用 -instances=static,因为 -instances=global 现在提供了静态的所有优点而没有其缺点。早期的编译器中提供了此选项来克服现已不存在的问题。


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

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

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

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


注 –

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


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

7.3.3 全局实例

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

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

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

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

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

7.3.4 显式实例

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

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

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

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

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

7.3.5 半显式实例

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

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