当前位置: 首页 > 科技观察

C++模板坑,一起来issue

时间:2023-03-19 16:15:37 科技观察

C++开发通常把类定义放在C++头文件(.h)里,把实现放在C++源文件(.cpp)里。然后,将源文件作为项目的一部分,即单独编译。但是,当我们为模板类实现这个过程时,会出现一些编译和链接问题。本文介绍了三种可能的解决方案,帮助您在实现模板的源文件中创建一个模板类对象来解决上述问题。问题再现头文件声明://temp.h#ifndef_TEMP_H_#define_TEMP_H_#include#includetemplateusingVec=std::vector;#definePRINTFMT(x)std::cout<voidTestTemp(constVec&v,Ttarget);#endif头文件实现:#include"temp.h"templatevoidTestTemp(constVec&v,Ttarget){[=](){for(autoelem:v)if(elem==target)PRINTFMT(elem);}();}Error:undefinedreferenceto....问题描述:当模板声明在.h,.cpp中时模板定义在.main函数实例化模板的时候,声明处找不到对应的T类型,自然就出问题了。1、第一种:同一个文件的声明和定义都在.h文件中。//temp.h#ifndef_TEMP_H_#define_TEMP_H_#include#includetemplateusingVec=std::vector;#definePRINTFMT(x)std::cout<voidTestTemp(constVec&v,Ttarget){[=](){for(autoelem:v)if(elem==target)PRINTFMT(elem);}();}#endif2。第二种:分离+导入头文件使用头文件声明和cpp定义。要工作,两者都必须在使用时引入,并且必须在定义时使用专门版本。例如:头文件实现://Temp.cpp#include"temp.h"voidTestTemp(constVec&v,inttarget){[=](){for(autoelem:v)if(elem==target)PRINTFMT(elem);}();}templatevoidTestTemp(constVec&v,Ttarget){[=](){for(autoelem:v)if(elem==target)PRINTFMT(elem);}();}实施:#include"temp.h"#include"temp.cpp"intmain(){std::vectorv{1,2,3};inttarget=2;TestTemp(v,target);return0;}3、要在最后引入cpp,只需要在.h头文件最后引入cpp即可。头文件只需要声明://temp.h#ifndef_TEMP_H_#define_TEMP_H_#include#includetemplateusingVec=std::vector;#definePRINTFMT(x)std::cout<voidTestTemp(constVec&v,Ttarget);#include"temp.cpp"#endifheaderfiledefinition://Temp.cpp#include"temp.h"templatevoidTestTemp(constVec&v,Ttarget){[=](){for(autoelem:v)if(elem==target)PRINTFMT(elem);}();}正常调用:#include"temp.h"intmain(){std::vectorv{1,2,3};inttarget=2;TestTemp(v,target);return0;}在一些开源项目中,这样比较常见,但是这里的.cpp要改成.hpp。其余不变!4.小结本节梳理了日常代码中的难点,并提出了几种解决方案。模板可以简单理解为一种特殊的宏。模板类不应被视为类。实例化的时候一定要找到它们的定义,不然只会看到声明,就GG了。

最新推荐
猜你喜欢