在目标文件中显式生成模板代码

explicit template code generation in object file

本文关键字:代码 目标 文件      更新时间:2023-10-16

如果我在一个单独的编译单元中有一个模板函数(它从CUDA C编译器NVCC产生一个后缀为。o的目标文件)

假设我们有定义(实现)

template<typename T> 
void foo(T a){
   // something
}

要在目标文件中生成显式代码,以便能够从另一个编译单元链接到它,我需要显式地实例化这个模板(对于我需要的所有模板参数):

template void foo<double>(double a);
template void foo<float>(double a);

这样做会在目标文件中产生实际的代码。

做其他事情,如:

template<> void foo<double>(double a);
template<> void foo<float>(float a);

不会在目标文件中产生代码,因为这是一个完全专门化的模板声明。这是正确的吗?

void foo(double a);
void foo(float a);

不产生代码,因为这将是一个重载声明 ?这是正确的吗?

现在的问题是,使编译器在单独的编译单元中为模板函数或类生成代码的通用语法是什么?

通俗地说,当您这样写时:

template void foo<double>(double a);
template void foo<float>(double a);

您显式地告诉编译器用正确的模板参数实例化函数模板,因此您得到foo<double>foo<float>的实现,就像您从函数模板中复制粘贴代码并用doublefloat替换T一样。

另一方面,当你这样写时:

template<> void foo<double>(double a);
template<> void foo<float>(float a);

你告诉编译器foo<double>foo<float>是完全不同的东西,与foo<T>没有任何关系。这被称为专门化。然而,您没有为这些专门化提供定义,而只是声明:您只是告诉编译器这些东西存在,而不是它们是什么。专门化的定义应该是这样的:

template<>
void foo<double>(double a) {
    // something else
}

根据你的意图,你可能想要:

  • 使用显式实例化(如果foo<double>foo<float>共享相同的实现)
  • 使用不同的专门化,同时为这些专门化提供实际的定义

我猜你想要第一个。