类中成员函数模板的显式实例化

时间:2019-06-26 09:54:53

标签: c++ class templates instance

我有一个包含在标题中声明为如下模板方法的类:

Class MyClass {
public :
   template <class T>
   int memberFunction(T& arg);
}

.cpp中的功能模板定义如下:

template<class T> int MyClass::memberFunction(T& arg){
    return arg*arg + arg + 0.2;
}

并在cpp文件中实例化如下:

template
int MyClass::memberFunction<int>(int&);

template
int MyClass::memberFunction<double>(double&);

代码在gcc和mscv下编译,但是每当我使用mscv函数时,都会返回警告消息,要求进行显式实例化。 我试图将实例化放在标题中,但会引发错误,该怎么办?

2 个答案:

答案 0 :(得分:2)

您可以在标头中提供显式的实例化声明:

Class MyClass {
public :
   template <class T>
   int memberFunction(T& arg);
};

extern template
int MyClass::memberFunction<int>(int&);

extern template
int MyClass::memberFunction<double>(double&);

此显式实例化声明虽然在这里并非严格要求,但可能足以安抚MSVC。

答案 1 :(得分:1)

您可以在标头中定义函数模板,以避免在myclass.h中出现类似链接的警告

class MyClass {
public :
   template <class T>
   T memberFunction(const T& arg) {
       return arg*arg + arg + 0.2;
   }
};

请注意模板成员函数声明中的更改。 您无需分开声明和定义,也无需明确定义 int和double类型的专业化,因为int和double的函数行为相同。注意可能的代码膨胀。 稍后,您可以使用如下功能

#include "myclass.h"
int main(int argc, char** argv) {

MyClass c1;
int res = c1.memberFunction(3);
printf("result=%d",res);
return 0;
}

并让编译器推断出参数的类型并隐式地对函数进行适当的实例化。如果您确实需要ant int从函数返回,则可以对结果进行一些强制转换。

如果您确实需要以在cpp文件中定义函数模板成员并抑制链接器警告的方式将模板成员函数的声明和定义分开,则可能是编译器相关的行为(如果使用编译器来处理)如果使用了export关键字,则可以使用它,也可以使用extern关键字(如果编译器支持)。在那种情况下,其想法是在标头中显式实例化模板函数,使编译器在处理cpp文件中的定义时具有适当的实例化,或者就像您在cpp文件中的所需类型上添加显式声明一样。