c++ 类中成员函数模板的显式示例化

gjmwrych  于 2023-07-01  发布在  其他
关注(0)|答案(2)|浏览(121)

我有一个类,它包含一个模板方法,在头部声明如下:

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时,都会返回一条警告消息,要求显式示例化。我试图把示例化放在头文件中,但它抛出错误,我应该怎么做?

33qvvth1

33qvvth11#

您可以在头文件中提供显式的示例化声明:

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的要求。

nxowjjhe

nxowjjhe2#

可以在头文件中定义函数模板,以避免链接器警告,类似于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从函数返回,你可以对result做一些强制转换。
如果你真的需要分离模板成员函数声明和定义,你需要在cpp文件中定义函数模板成员并抑制链接器警告,这可能是编译器相关的行为来处理,如果你使用的编译器具有depricated export关键字,你可以使用它或使用extern关键字,如果编译器支持的话。在这种情况下,这个想法是显式地在头文件中示例化模板函数,编译器在处理cpp文件中的定义时有适当的示例化,或者像你在cpp文件中添加所需类型的显式声明一样。

相关问题