Bootstrap

C++函数模板的分离编译

1.分离编译模式:
一个程序由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有的目标文件链接起来形成但一个可执行文件的过程称为分离编译模式。
但是这种分离编译在C++中是不支持的。
2.使用模板在链接时会出错。

如下:
下面的程序由三个文件组成:func.h用来对函数模板进行声明,func.cpp用来定义函数模板,main.cpp包含func.h头文件并调用相应的函数模板。

func.h文件:

#include<iostream>
using namespace std;
template<class T>
void func(const T&);

func.cpp文件:

#include"fun.h"
template<class T>
void func(const T&t)
{
    cout << t << endl;
}

main.cpp文件:

#include"fun.h"
int main()
{
    func(3);
    system("pause");
    return 0;
}

这里写图片描述
发现编译不通过:原因是:
原因发生在分离编译上,在分离编译模式上,func.cpp会生成一个func.obj,由于在func.cpp文件中,并没有发生函数模板调用,所以不会将函数模板func<T>实例化为模板函数func<int>,即在func.obj中无法找到关于模板函数func<int>的实现代码。在源文件main.cpp中,虽然函数模板被调用但由于没有模板代码,也不能将其实例化。也就是说,在main.obj中也找不到模板函数func< int>的实现代码。

解决方法:
1.将函数模板的定义与声明都放到头文件中。(推荐使用该方法)
这个办法虽然简单可行,但是有如下不足。
(1)函数模板的定义写进了头文件,暴露了函数模板的实现细节。

(2)不符合分离编译模式的规则,因为分离编译模式要求函数原型申明放在头文件,定义放在源文件。
func.h

#include<iostream>
using namespace std;
template<class T>
void func(const T&);
template<class T>
void func(const T&t)
{
    cout << t << endl;
}

main.cpp

#include<iostream>
using namespace std;
#include"fun.h"
int main()
{
    func(3);
    system("pause");
    return 0;
}

2.在模板头文件(func.h)或func.cpp文件中显示实例化—->模板类的定义后面添加:

template void func<int>(const int&);//函数模板显示实例化

func.h

#include<iostream>
using namespace std;
template<class T>
void func(const T&t);

func.cpp

#include"fun.h"
template<class T>
void func(const T&t)
{
    cout << t << endl;
}
template void func<int>(const int&);//函数模板显示实例化

main.cpp

#include"fun.h"
int main()
{
    func(3);
    system("pause");
    return 0;
}
;