我正在开发一个静态库,该库有多个类模板和函数模板.我理解为了使用静态库中的模板,所有(声明/定义)都需要在头文件中.但是,在这种特殊情况下,因为我知道我认为可以使用的特化类型转发声明专门化.
这个技巧与类模板(及其函数)很好地协作,我可以使用我的应用程序代码中的所有库函数.然而,当我介绍免费函数模板库中,我尝试使用免费的模板功能从我的应用程序代码,它给了我链接错误:
错误LNK2019:未解析的外部符号"类TemplatedStaticLib __cdecl HelpingRegistration(int)"(?? $ HelpingRegistration @ H @@ YA?AV?$ TemplatedStaticLib @ H @@ H @ Z)在函数_main 1> C:\ src\cpp中引用\ vs2008\StaticLibExample\MathFuncsLib\Debug\TemplatedStaticLibApp.exe:致命错误LNK1120:1未解析的外部"我正在使用VS2008,这里是代码
//静态库头文件(.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
Run Code Online (Sandbox Code Playgroud)
//静态库类文件(.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;
}
Run Code Online (Sandbox Code Playgroud)
//应用程序代码
#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;
}
Run Code Online (Sandbox Code Playgroud)
我不确定为什么会有所不同以及如何解决这个问题.任何帮助表示赞赏.
请注意,这些不是前向声明,而是您的类模板的明确实例化.这就是允许您将定义放在.cpp文件中并且链接器不会得到任何未解析的引用错误的原因,只要在其他转换单元中您只使用这些模板实例化.
另一方面,这些:
template<> TemplatedStaticLib<int> HelpingRegistration<int>(int);
template<> TemplatedStaticLib<double> HelpingRegistration<double>(double);
template<> TemplatedStaticLib<std::string> HelpingRegistration<std::string>(std::string);
Run Code Online (Sandbox Code Playgroud)
是函数模板的显式特化的声明.相反,您最想要做的是提供明确的实例化.这样做的语法如下:
template TemplatedStaticLib<int> HelpingRegistration<>(int);
template TemplatedStaticLib<double> HelpingRegistration<>(double);
template TemplatedStaticLib<std::string> HelpingRegistration<>(std::string);
Run Code Online (Sandbox Code Playgroud)
一旦你解决了这个问题,你会发现编译器实际上会实例化你的HelpingRegistration<>()函数模板,并且在执行此操作时也会发出错误,因为你试图将int(分别为a double或string)转换为类型的对象TemplatedStaticLib<int>(resp) .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!
}
Run Code Online (Sandbox Code Playgroud)
修复此错误(例如,通过执行return TemplateStaticLib<T>();)将使程序编译和链接.
| 归档时间: |
|
| 查看次数: |
6092 次 |
| 最近记录: |