【问题标题】:Are explicit template instantiation declarations required in the header when explicitly instantiating the definitions in the source file?显式实例化源文件中的定义时,是否需要在标头中显式模板实例化声明?
【发布时间】:2018-06-28 15:53:13
【问题描述】:

this question 中,接受的答案涉及头文件中的模板函数declaration,其定义 在源文件中。为了使这个模板函数也可以在其他翻译单元中使用,在源文件中为每个“允许的”使用进行了显式模板实例化。到目前为止,这在我看来是标准做法。

不过,答案还建议将相应的显式模板实例化声明放在头文件中。我以前没有见过这种做法,想知道标准是否要求这样做。

这是一个小例子:

啊.h

struct A
{
    template<class T>
    void g(T t);
};

A.cpp

#include "A.h"

template<class T>
void A::g(T t)
{ /* ... */ }

template void A::g(int); // Explicit instantiation of the definition.

ma​​in.cpp

#include "A.h"

int main()
{
    A a;
    a.g(0);
}

wording in the standard 并没有告诉我是否还需要显式实例化 声明。这似乎主要涉及“定义从未显式实例化,A.cpp 中的隐式实例化不保证被保留”的情况(未描述),但我希望得到澄清。

【问题讨论】:

  • 我不明白它是/可能需要的。无论如何,只要您使用 main.cpp 中的函数,您就会隐含地这样做。归根结底,这是一个翻译单元的问题,一旦main.cpp 执行的那个看到a.g(0);,结果就是从A.h 本身解析和扩展为仅decl 模板A,它会根据需要进行扩展(尚未完成对于那个 TU)。
  • 据我了解,您的代码没问题(省略 A.cpp 中缺少的 #include "A.h")。
  • 我正在检查其他东西,当我发现这个(尽管不是规范的)示例时:timsong-cpp.github.io/cppwp/n4659/temp.over#5 我认为它进一步有助于巩固 Barry 突出显示的句子的意图。

标签: c++ language-lawyer template-specialization


【解决方案1】:

当显式实例化源文件中的定义时,是否需要在标头中显式模板实例化声明?

没有。规则是,来自[temp]/10,强调我的:

函数模板、类模板的成员函数、变量模板或类模板的静态数据成员应在隐式实例化的每个翻译单元中定义除非相应的特化在某些情况下显式实例化翻译单元;不需要诊断。

在您的示例中,A::g&lt;int&gt;main.cpp 中隐式实例化,但在“某个翻译单元”(A.cpp)中显式实例化。程序很好。

【讨论】:

    猜你喜欢
    • 2014-09-23
    • 1970-01-01
    • 1970-01-01
    • 2017-06-11
    • 1970-01-01
    • 1970-01-01
    • 2018-07-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多