mar*_*olk 44 c++ templates compiler-errors
我几乎不知道C++模板会发生什么,但我正在尝试实现一个函数,它在向量中搜索满足给定属性的元素(在这种情况下,搜索名称给定的元素).我在.h文件中的声明如下:
template <typename T>
T* find_name(std::vector<T*> v, std::string name);
Run Code Online (Sandbox Code Playgroud)
当我编译时,我在调用函数时遇到此链接器错误:
Error 1 error LNK2019: unresolved external symbol "class Item * __cdecl find_name<class Item>(class std::vector<class Item *,class std::allocator<class Item *> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??$find_name@VItem@@@@YAPAVItem@@V?$vector@PAVItem@@V?$allocator@PAVItem@@@std@@@std@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z) referenced in function "public: class Item * __thiscall Place::get_item(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?get_item@Place@@QAEPAVItem@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) place.obj Program2
Run Code Online (Sandbox Code Playgroud)
同样,我是模板的新手,所以我不知道会发生什么.我通过谷歌找到的LNK2019的所有实例都没有使用正确的库,但由于这是我自己的功能,我不明白为什么会发生这种情况.
另外,一个相关的问题:是否有办法制作模板参数,以便它必须是某个类的子类,即模板?
GMa*_*ckG 74
您必须在调用站点上提供模板定义.这意味着没有.cpp
文件.
原因是模板无法编译.将功能视为cookie,编译器是烤箱.
模板只是一个千篇一律,因为他们不知道它们是什么类型的cookie.它只告诉编译器在给定类型时如何创建函数,但是它本身不能使用它,因为没有操作的具体类型.你不能煮饼干.只有当您准备好美味的饼干面团时(即,给予编辑器面团[类型]),您可以切割饼干并烹饪它.
同样,只有当您实际使用具有特定类型的模板时,编译器才能生成实际函数并进行编译.但是,如果缺少模板定义,则无法执行此操作.您必须将其移动到头文件中,因此函数的调用者可以创建cookie.
CB *_*ley 51
您可能正在缺少有效的实例化.如果将模板定义放在单独的.cpp文件中,则当编译器编译该文件时,它可能不知道您需要哪个实例.相反,在将实例化模板函数的正确版本的调用站点,如果函数体的定义不可用,则编译器将不具有实例化所需特化的信息.
你有两个选择.将函数模板的函数体放在头文件中.
例如在头文件中:
template <typename T>
inline T* find_name(std::vector<T*> v, std::string name)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
或者在您定义模板的.cpp中显式实例化模板.
例如在源文件中(可能需要#include
定义的文件Item
):
template <typename T>
T* find_name(std::vector<T*> v, std::string name)
{
// ...
}
template Item* find_name<Item>(std::vector<Item*> v, std::string name);
Run Code Online (Sandbox Code Playgroud)
cho*_*ida 11
这里的答案很棒.
我只想补充一点,这通常是除了项目中的文件.h
和.cpp
文件之外的原因.你经常会找到.inl
文件.模板定义将进入.inl
文件.
这些.inl
文件意味着内联,并且通常.h
在所有标头声明之后由文件底部的相同名称前缀的文件包含.这有效地使它们成为头文件的一部分,但将声明与任何定义分开.
由于它们是美化的头文件,您应该采取与常规头文件相同的预防措施,即包括警卫等.
偶然发现相同的问题,发现它指出了3种解决方法:http : //www.codeproject.com/Articles/48575/How-to-define-a-template-class-in-ah-file-and-imp
其中一种是简单的方法,您可以在.cpp文件中创建一个“虚拟”方法,该方法以不同的类型调用模板/类函数。从链接粘贴:
// No need to call this TemporaryFunction() function, it's just to avoid link error.
void TemporaryFunction ()
{
TestTemp<int> TempObj;
TestTemp<float> TempObj2;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
33745 次 |
最近记录: |