使用独立定义模板组织时,模板定义在当前编译单元不可用,编译器必须搜索该定义。本节描述了编译器如何找到定义。
定义搜索有些复杂,并且很容易出现错误。因此如果可能,您应该使用定义包括模板文件组织。这样有助于避免一起定义搜索。请参见5.2.1 包括的模板定义。
如果使用 -template=no%extdef 选项,编译器将不搜索单独的源文件。
如果没有随选项文件一起提供的特定方向,则编译器使用 Cfront 样式的方法来定位模板定义文件。此方法要求模板定义文件包含的基名与模板声明文件包含的基名相同。此方法也要求模板定义文件位于当前 include 路径中。例如,如果模板函数 foo() 位于 foo.h 中,则匹配的模板定义文件应该命名为 foo.cc 或某些其他可识别的源文件扩展名(.C、.c、.cc、.cpp、.cxx 或 .c++)。模板定义文件必须位于常规的 include 目录之一中,或位于与其匹配的头文件所在目录中。
可以用另外一种方法替代用–I设置的常规搜索路径,即使用选项 –ptidirectory 指定模板定义文件的搜索目录。多个 -pti 标志定义多个搜索目录-即搜索路径。如果使用 -ptidirectory,则编译器在该路径查找模板定义文件并忽略 –I 标志。由于 –ptidirectory 标志会使源文件的搜索规则变得复杂,因此使用 –I 选项代替 –ptidirectory 选项。
有时,编译器会生成令人费解的警告或错误消息,因为它会查找您不打算编译的文件。此问题通常是由于某个文件(如 foo.h)包含模板声明,且隐式包含了另一个文件(如 foo.cc)。
如果头文件 foo.h 有模板声明,则在缺省情况下,编译器将搜索名为 foo 且有 C++ 文件扩展名( .C、.c、.cc、.cpp、.cxx 或 .c++)的文件。如果找到这样的文件,编译器将自动把它包含进来。有关这些搜索的更多信息,请参见7.5 模板定义搜索。
如果有一个不打算这样处理的文件 foo.cc,有两种解决方法:
更改 .h 或 .cc 文件的名称,以消除名称匹配。
通过指定 -template=no%extdef 选项禁止自动搜索模板定义文件。然后必须在代码中显式包含所有模板定义,并且不能使用“独立定义”模型。