为什么这个模板示例代码没有编译
Why is this template example code not compiling?
为了学习如何使用模板,我正在尝试制作一个使用模板的示例。我在Visual Studio 2010 C++中用三个文件做了一个项目:
Controller.cpp:
#include <iostream>
#include "Foo.h"
using namespace std;
int main(){
Example<int,string> example;
example.appols(5, "Hi");
return 0;
}
Foo.h:
#include <iostream>
using namespace std;
template <class T, class E>
class Foo{
public:
void printThis(T t, E e);
};
template <class T, class E>
class Example{
public:
void appols(T t, E e);
};
Foo.ipp:
#include <iostream>
#include "Foo.h"
using namespace std;
template<class T, class E>
void Foo<T, E>::printThis(T t, E e){
cout << "FOO! " << t << ' ' << e << endl;
}
template<class T, class E>
void Example<T, E>::appols(T t, E e){
cout << "APPOLS!! " << t << ' ' << e << endl;
Foo<T,E> f;
f.printThis(t,e);
}
当我尝试编译时,我得到:
1>------ Build started: Project: Template Practive, Configuration: Debug Win32 ------
1>Controller.obj : error LNK2019: unresolved external symbol "public: void __thiscall Example<int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::appols(int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?appols@?$Example@HV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@QAEXHV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function _main
1>C:UsersMatthewdocumentsvisual studio 2010ProjectsTemplate PractiveDebugTemplate Practive.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
你能帮我看看我在这里做错了什么吗?error LNK2019
是从哪里来的?提前谢谢!
解密错误消息
让我们先尝试解码错误消息:
1>Controller.obj : error LNK2019: unresolved external symbol "public: void __thiscall Example<int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::appols(int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?appols@?$Example@HV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@QAEXHV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function _main
我们可以在这个错误消息中开始降低信噪比。
(?appols@?$Example@HV?$basic_string@DU?$char_traits@D@std@@...
的部分只是C++名称篡改。它是为C++编译器设计的,并不是为了让人可读。所以我们可以丢弃它。
简化的错误消息变为:
1>Controller.obj : error LNK2019: unresolved external symbol "public: void __thiscall Example<int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::appols(int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" referenced in function _main
第一行告诉我们存在一个"未解析的外部符号"。让我们试着识别它,看看下一行。
零件:
class std::basic_string<char,struct std::char_traits<char>...
只是std::string
的长名称(对应于以char
为字符类型并使用默认char
特征和默认分配器的std::basic_string
模板)。
因此,我们可以用std::string
代替那些冗长的部分来进一步降低噪声:
1>Controller.obj : error LNK2019: unresolved external symbol "public: void __thiscall Example<int,string>::appols(int,string)" referenced in function _main
现在这个错误更清楚了。
__thiscall
部分只是默认情况下用于C++成员函数的调用约定。
因此,链接器正在抱怨这种方法:
"public: void Example<int,string>::appols(int,string)"
对应于您的Example<T,E>::appols()
:
template <class T, class E> class Example{ public: void appols(T t, E e); };
当CCD_ 10和CCD_。
这与Controller.cpp中main()
函数中的内容相对应:
Example<int,string> example; example.appols(5, "Hi");
问题的诊断和解决方案
问题是,所有模板源代码必须在头文件中,而不是.cpp文件中。
事实上,编译器需要模板代码的定义来实例化它
因此,您可以将代码从Foo.ipp文件移动到Foo.h(或仅从Foo.h移动#include "Foo.ipp"
),并将inline
添加到模板函数定义中:
// New code in Foo.h
template<class T, class E>
inline void Foo<T, E>::printThis(T t, E e){
cout << "FOO! " << t << ' ' << e << endl;
}
template<class T, class E>
inline void Example<T, E>::appols(T t, E e){
cout << "APPOLS!! " << t << ' ' << e << endl;
Foo<T,E> f;
f.printThis(t,e);
}
还要注意的是,using namespace std;
在头文件中非常糟糕,因为这会污染所有包含头的客户端的全局命名空间。只需在头文件中明确使用std::
前缀(例如:std::cout
、std::endl
等)。
- 如何修复sfml c++代码编译错误
- 尝试用java代码编译和运行c++代码
- 此代码编译良好,但文件未创建?请指出错误
- 为什么我的 BaseClass:Method 代码编译(带有单冒号)?
- 代码编译没有任何输出,入门程序
- 通过Python Distutils(用于Python C扩展)使用可重定位的设备代码编译CUDA代码
- 代码编译但不起作用!cmd窗口只是理想和理想,但什么也没发生
- 无法使用 g++ 使用C++代码编译 C 库
- 如何在Ubuntu中使用Visual Studio代码编译C++代码
- 推力+提升代码编译错误
- C++代码编译,但在 Zorin OS 上运行时显示错误
- 如何在使用模板时将 CPP 代码编译到库文件中
- 是否可以将Visual Studio 2017将C 代码编译到EXE以外的文件类型中
- 使用 Visual Studio for C++ 代码编译错误
- 使用 Android Studio 使用本机代码编译 apk 时,如何在链接处删除 libgnustl_static.
- 使用 Emscripten 将 OpenCV 代码编译C++ Javascript
- 将C 代码编译到独立应用程序.App
- 为什么此代码编译 (C++11) 而没有类型不匹配错误
- 重用编译器前端的结果,以加快多个配置/平台的C++代码编译
- 如何将C++11代码编译为网络汇编