存在问题的代码:
test.h:
#include
using namespace std;
template
void func(T1 t1,T2 t2);
test.cpp:
#include "test.h"
using namespace std;
template
void func(T1 t1,T2 t2)
{
cout<
main.cpp:
#include "test.h"
int main()
{
string str("ljt");
int i=5;
func(str,5);
}
编译结果:
[root@localhost cpptest]# g++ test.cpp test.h main.cpp -o test
/tmp/ccp1HXnh.o:在函数‘main’中:
main.cpp:(.text+0x5d):对‘void func(std::string, int)’未定义的引用
collect2: 错误:ld 返回 1
说明了在main.cpp中没有找到函数func的定义。
查看原因:
对test.cpp只进行编译不进行链接:
[root@localhost cpptest]# g++ -c test.cpp
[root@localhost cpptest]# nm -C -n test.o
U __cxa_atexit
U __dso_handle
U std::ios_base::Init::Init()
U std::ios_base::Init::~Init()
0000000000000000 t __static_initialization_and_destruction_0(int, int)
0000000000000000 b std::__ioinit
000000000000003d t _GLOBAL__sub_I_test.cpp
会发现符号表中不存在func函数,也就是编译出的二进制文件没有为func分配内存空间。
原因是:模板只有在使用的时候才进行实例化。
改正后代码:
test.cpp:
#include "test.h"
using namespace std;
template
void func(T1 t1,T2 t2)
{
cout<
编译后:
[root@localhost cpptest]# g++ -c test.cpp //-c:只编译不链接
[root@localhost cpptest]# nm -C -n test.o
U __cxa_atexit
U __dso_handle
U __gxx_personality_v0
w __pthread_key_create
U _Unwind_Resume
U std::ostream::operator<<(int)
U std::ostream::operator<<(std::ostream& (*)(std::ostream&))
U std::basic_string, std::allocator >::basic_string(std::string const&)
U std::basic_string, std::allocator >::~basic_string()
U std::ios_base::Init::Init()
U std::ios_base::Init::~Init()
U std::cout
U std::basic_ostream >& std::endl >(std::basic_ostream >&)
U std::basic_ostream >& std::operator<< , std::allocator >(std::basic_ostream >&, std::basic_string, std::allocator > const&)
0000000000000000 W void func(std::string, int)
0000000000000000 T func1(std::string, int)
0000000000000000 b std::__ioinit
0000000000000000 r __gthread_active_p()::__gthread_active_ptr
0000000000000063 t __static_initialization_and_destruction_0(int, int)
00000000000000a0 t _GLOBAL__sub_I__Z5func1Ssi
可以看到函数符号func1(std::string, int)、void func
[root@localhost cpptest]# g++ test.cpp test.h main.cpp -o test
[root@localhost cpptest]# ls -rtl
总用量 32
-rw-r--r-- 1 root root 92 12月 21 10:41 test.h
-rw-r--r-- 1 root root 172 12月 21 13:00 test.cpp
-rw-r--r-- 1 root root 86 12月 21 13:00 main.cpp
-rw-r--r-- 1 root root 3912 12月 21 13:01 test.o
-rwxr-xr-x 1 root root 13952 12月 21 13:03 test
[root@localhost cpptest]# ./test
ljt5
也可成功生成test。
采用此种方式,如果我们在外部调用一个func(str,"5");,依然会报错,因为未对func(string,string)进行实例化调用,没有生成对应的符号。
模板分离的解决办法:
1、文件(.h/.cpp)分离,在cpp中对每种情况进行实例化调用
template
void func(T1 t1,T2 t2)
{
cout<
2、声明和定义都放到.h中(STL)
相当于在cpp中进行实例化,在.h中完成声明和定义,但是这个违背了分离编译的思想。
test.h
#include
using namespace std;
template
void func(T1 t1,T2 t2);
template
void func(T1 t1,T2 t2)
{
cout<
参考: https://www.cnblogs.com/downe...