gpt4 book ai didi

c++ - 具有模板实例化的模板静态库

转载 作者:可可西里 更新时间:2023-11-01 18:28:28 28 4
gpt4 key购买 nike

我正在处理一个静态库,该库有多个类模板和函数模板。我知道为了在静态库中使用模板,所有内容(声明/定义)都需要在头文件中。但是,在这种特殊情况下,因为我知道我认为我可以使用前向声明特化的特化类型。

这个技巧与类模板(及其函数)配合得很好,我可以使用我的应用程序代码中的所有库函数。但是,一旦我在库中引入免费函数模板并尝试使用我的应用程序代码中的免费模板函数,它就会给我链接器错误:

error LNK2019: unresolved external symbol "class TemplatedStaticLib __cdecl HelpingRegistration(int)" (??$HelpingRegistration@H@@YA?AV?$TemplatedStaticLib@H@@H@Z) referenced in function _main 1>C:\src\cpp\vs2008\StaticLibExample\MathFuncsLib\Debug\TemplatedStaticLibApp.exe : fatal error LNK1120: 1 unresolved externals" I am using VS2008, here is the code

//静态库头文件(.h)

#ifndef _TEMPLATED_STATIC_LIB_
#define _TEMPLATED_STATIC_LIB_

#include <iostream>

template<typename T>
class TemplatedStaticLib
{
public:
TemplatedStaticLib(){};
~TemplatedStaticLib(){};

void print(T t);

};

template<typename T>
TemplatedStaticLib<T> HelpingRegistration(T);


#endif

//静态库类文件(.cpp)

#include "TemplatedStaticLib.h"

//Specialization
template class TemplatedStaticLib<double>;
template class TemplatedStaticLib<int>;
template class TemplatedStaticLib<std::string>;


template<typename T>
void TemplatedStaticLib<T>::print(T t)
{
std::cout << "Templated Print " << typeid(t).name() << std::endl;
}

void HelpingRegistration(void)
{
}

//Specialization of free function
template<> TemplatedStaticLib<int> HelpingRegistration<int>(int);
template<> TemplatedStaticLib<double> HelpingRegistration<double>(double);
template<> TemplatedStaticLib<std::string> HelpingRegistration<std::string>(std::string);

template<typename T>
TemplatedStaticLib<T> HelpingRegistration(T t)
{
std::cout << "Function Templated Print " << typeid(t).name() << std::endl;
return t;
}

//应用代码

#include "TemplatedStaticLib.h"

int main(int argc, char* argv[])
{
int anInt = 99;
TemplatedStaticLib<int> test;
test.print(anInt);//works

double aDouble = 3.9;
TemplatedStaticLib<double> double_test;
double_test.print(aDouble); //works

std::string aString = "James";

TemplatedStaticLib<std::string> string_test;
string_test.print(aString);//works

//The following lines gives linker error
HelpingRegistration(anInt);
HelpingRegistration(aDouble);
HelpingRegistration(aString);


return 0;
}

我不确定为什么会有所不同以及如何解决这个问题。任何帮助表示赞赏。

最佳答案

请注意,这些不是前向声明,而是类模板的显式实例化。这就是允许您将定义放在 .cpp 中的原因。文件并且链接器不会出现 Unresolved 引用错误,只要在其他翻译单元中您只使用这些模板实例化即可。

另一方面,这些:

template<> TemplatedStaticLib<int> HelpingRegistration<int>(int);
template<> TemplatedStaticLib<double> HelpingRegistration<double>(double);
template<> TemplatedStaticLib<std::string> HelpingRegistration<std::string>(std::string);

是函数模板的显式特化声明。相反,您最有可能打算做的是提供显式实例化。这样做的语法如下:

template TemplatedStaticLib<int> HelpingRegistration<>(int);
template TemplatedStaticLib<double> HelpingRegistration<>(double);
template TemplatedStaticLib<std::string> HelpingRegistration<>(std::string);

一旦你解决了这个问题,你就会看到编译器实际上会实例化你的HelpingRegistration<>()函数模板,它也会在这样做时发出错误,因为您正在尝试转换 int (分别为 doublestring )到 TemplatedStaticLib<int> 类型的对象(分别为 TemplatedStaticLib<double>TemplatedStaticLib<string> ),没有提供转换(或者至少没有在您发布的代码中显示):

template<typename T>
TemplatedStaticLib<T> HelpingRegistration(T t)
{
std::cout << "Function Templated Print " << typeid(t).name() << std::endl;
return t; // CANNOT BE CONVERTED!
}

修复此错误(例如通过执行 return TemplateStaticLib<T>(); )将使程序编译链接。

关于c++ - 具有模板实例化的模板静态库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15079578/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com