【问题标题】:explicit template code generation in object file [duplicate]目标文件中的显式模板代码生成
【发布时间】:2014-05-27 14:16:02
【问题描述】:

如果我在单独的编译单元中有一个模板函数(它从 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);

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

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

【问题讨论】:

  • 您的完整专用模板声明只是一个声明。那里没有定义,因此没有代码。它不是实例化。 (顺便说一句,这与 CUDA 无关)。
  • 你说得对,它不会“产生代码”。要在编译单独的编译单元时“生成代码”,您需要在编译时(而不是链接时)访问模板声明和定义,从这里所有关于标头中的模板或显式实例化的讨论。因此,要让编译器为模板函数或类生成代码在编译时另一个编译单元您需要访问声明/定义,然后使用它显式将其实例化 到该单元中。始终坚持 ODR。

标签: c++ templates compiler-construction object-files


【解决方案1】:

通俗地说,当你写这个时:

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

您明确告诉编译器实例化具有正确模板参数的函数模板,因此您将获得foo&lt;double&gt;foo&lt;float&gt; 的实现,就像您复制粘贴的代码一样函数模板并将T替换为doublefloat

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

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

您告诉编译器foo&lt;double&gt;foo&lt;float&gt;完全不同的东西,与foo&lt;T&gt; 没有任何关系。这称为专业化。但是,您并没有为这些特化提供定义,而只是声明:您只是告诉编译器这些东西存在,而不是它们是什么时间>。专业化的定义如下所示:

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

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

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

我猜你想要第一个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-06
    • 2014-07-14
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    • 2010-09-16
    相关资源
    最近更新 更多