问题:
在GCC下编写C++模板函数报undefined reference to错误,找了一系列文章研究。
一类是链接的问题
1. 链接时缺失了相关目标文件(.o)
2. 链接时缺少相关的库文件(.a/.so)
3. 链接的库文件中又使用了另一个库文件
4. 多个库文件链接顺序问题
5. 定义与实现不一致
6. 在C++代码中链接C语言的库
[转]"undefined reference to" 问题解决方法 - 筱陌 - 博客园
https://www.cnblogs.com/QQ-1615160629/p/6233866.html
"undefined reference to" 问题解决方法 - aiwoziji13的专栏 - CSDN博客
https://blog.csdn.net/aiwoziji13/article/details/7330333
"undefined reference to" 问题汇总及解决方法 ------非常非常好的一篇文章 - stpeace的专栏 - CSDN博客
https://blog.csdn.net/stpeace/article/details/73302833
"undefined reference to" 问题汇总及解决方法 - 残剑 - SegmentFault 思否
https://segmentfault.com/a/1190000006049907?utm_source=tuicool&utm_medium=referral
另一类是C++的name mangling技术的问题
解决 undefined reference to 问题 - haithink的专栏 - CSDN博客
https://blog.csdn.net/haithink/article/details/80693496
Name Mangling in C++-相信并热爱着-51CTO博客
http://blog.51cto.com/hipercomer/855223
尝试:
按照这个链接问题中的6个依次排查没有找出问题,最后不使用泛型成功运行。推测是在C++泛型编程时某一个依赖库没有加进来,或者是C++的name mangling技术使得函数名发生变化,有待进一步研究。
最终发现是g++编译器本身的问题,不支持模板的分离编译。
例如:
template<typename T>
void SwapType(T &a, T &b)
在调用int时,会生成一个template void SwapType<int>(int &a, int &b)的实例,编译器在头文件中找不到该定义。
解决:
1. 把实现方法直接写在头文件里
2. 将实现方法全写在另一个文件里,然后在头文件的结尾包含该文件
3. 在头文件对应的实现文件里添加具体类型的函数声明,例如:
//template void SwapType<int>(int &a, int &b);
//template void SwapType<char>(char &a, char &b);
c++ - Why can templates only be implemented in the header file? - Stack Overflow
https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file
Standard C++
https://isocpp.org/wiki/faq/templates#templates-defn-vs-decl
// File: main.cpp
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
#include "swap.h"
int main()
{
int a,b;
a=1,b=2;
cout<<"a="<<a<<" b="<<b<<endl;
SwapT(a,b);
cout<<"a="<<a<<" b="<<b<<endl;
return 0;
}
// File: swap.h
//template<typename T>
//void SwapT(T &a, T &b);
/* 方法一:实现方法直接写在头文件里 */
template<typename T>
void SwapT(T &a, T &b)
{
T temp = a;
a = b;
b = temp;
return;
}
/* 方法二:实现方法写在其它文件里,然后包含在头文件的结尾 */
//#include "swap.tpp"
// File: swap.cpp
#include "swap.h"
/* 方法三:添加使用到的具体类型的函数声明 */
//template void SwapType<int>(int &a, int &b);
//template void SwapType<char>(char &a, char &b);
// File: swap.tpp
template<typename T>
void SwapType(T &a, T &b)
{
T temp = a;
a = b;
b = temp;
return;
}