如何正确地显式实例化具有完全专用成员的模板类

How to properly explicitly instantiate a template class with fully-specialized members?

本文关键字:成员 专用 正确地 实例化      更新时间:2023-10-16

假设我们有以下文件:

foo.h

namespace ns
{
template <typename T>
class Foo
{
public:
Foo();
~Foo();
void DoIt();
};
}

foo.cpp

#include "foo.h"
#include <iostream>
namespace ns
{
template <typename T>
Foo<T>::Foo() { std::cout << "Being constructed." << std::endl; }
template <typename T>
Foo<T>::~Foo() { std::cout << "Being destroyed." << std::endl; }
template <>
void Foo<int>::DoIt()
{
std::cout << "Int" << std::endl;
}
template <>
void Foo<double>::DoIt()
{
std::cout << "Double" << std::endl;
}
template class Foo<int>;
template class Foo<double>;
}

假设类型只与int或double一起用作类型参数,那么这是进行显式实例化的正确方法吗?或者您还需要在头文件中声明显式专用化吗?

按照我在visual studio中展示的方式进行操作,但一位同事在GCC方面遇到了问题(虽然我刚刚检查过,我认为这是由于其他原因,但我还是会发布这个问题)

[温度解释规范]/p6(强调矿):

如果模板、成员模板或类模板的成员明确地专门化,则应声明专门化在第一次使用会导致在每个翻译单元中进行隐式实例化发生这种使用;不需要进行诊断。

事实上,如果将它们组合在一个TU中,clang和gcc都会发出错误。您需要声明这些明确的专业化。


由于我们真的很接近它,我也只引用[temp.exp.spec]/p7,因为我可以:

函数显式专用化声明的位置模板、类模板、变量模板、的成员函数类模板,类模板的静态数据成员,成员类模板的类、类模板的成员枚举,类模板的成员类模板,成员函数模板类模板的静态数据成员模板,类模板的成员模板的成员函数,成员非模板类的成员模板的函数,静态数据非模板类的成员模板,的成员函数模板类模板的成员类等,以及局部类模板、变量模板的专门化声明,非模板类的成员类模板,静态数据成员非模板类的模板,类的成员类模板模板等会影响程序是否根据显性专业化的相对定位声明及其在翻译单元中的实例化点如上文和下文所述。在撰写专业文章时小心它的位置;或者将其编译将是一种尝试以点燃它的自焚。