如果我在一个单独的编译单元中有一个模板函数(它从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);
不生成代码,因为这是过载声明?这是对的吗?
现在的问题是,使编译器在单独的编译单元中为模板函数或类生成代码的一般语法是什么?
答案 0 :(得分:3)
用非专业术语来说,当你写这篇文章时:
template void foo<double>(double a);
template void foo<float>(double a);
您明确告诉编译器使用正确的模板参数实例化函数模板,因此您获得了foo<double>
和foo<float>
的实现,就像您有副本一样粘贴了功能模板中的代码,并将T
替换为double
和float
。
另一方面,当你写这个:
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>
共享相同的实现)我猜你想要第一个。