函数模板分为普通函数模板和具体化函数模板
普通函数模板:函数模板只是函数的描述符,没有实体,创建函数模板的代码整体放在头文件中;
具体化函数模板:具体化函数模板有实体,编译时和普通函数一样,所以声明放在头文件中,定义放在源文件中;
以下是未分文件书写时的代码:
main.cpp
#include <iostream>
using namespace std;
// 普通函数
void test(int a,int b)
{
cout <<"调用了普通函数"<<endl;
}
// 函数模板
template<typename tab>
void test(tab a,tab b)
{
cout <<"调用了普通函数模板"<<endl;
}
// 具体化函数模板
template<>
void test(int a,int b)
{
cout <<"调用了具体化函数模板"<<endl;
}
int main()
{
test(10,20);
test('a','c');
test<>(2,5);
}
下面是分文件书写的代码,我直接给出结果:
public.h
#ifndef __PUBLIC_H__
#define __PUBLIC_H__
#include <iostream>
using namespace std;
// 普通函数声明
void test(int a, int b);
// 普通模板只是函数的描述,没有实体,所以应该全部放到头文件中
template<typename tab>
void test(tab a, tab b)
{
cout << "使用了普通函数模板" << endl;
}
// 具体化函数模板有实体,编译的原理和普通函数一样,所以头文件声明
template<>
void test(int a, int b);
#endif
public.cpp
#include "public.h"
// 普通函数实现
void test(int a,int b)
{
cout << "使用了普通函数" << endl;
}
// 具体化模板实现
template<>
void test(int a,int b)
{
cout << "使用了具体化函数模板" << endl;
}
main.cpp
#include "public.h"
int main()
{
test(10, 20);
test('a', 'c');
test<>(20, 30);
}
可以正常编译,且运行的结果是一样的;
首先需要注意的是:函数模板的声明要在具体化模板的上方
另外,上面我们是把函数模板的整个代码都放到了头文件中,这是正确的,如果分文见书写,会出错,如下:
编译没问题:
运行:
先把代码还原
如果把具体化模板的声明和实现都放到头文件中,也会出错,如下:
编译:
没有问题,运行:
总结
1、具体化函数模板的声明要放到普通函数模板的下方
2、函数模板只是函数的描述符,没有实体,应该把整个函数模板放到头文件中;具体化函数模板有实体,编译过程和普通函数一样,所以应该把声明放到头文件中,实现放到源文件中
以上只是一种编程习惯,可能会有其他办法把普通函数模板的声明和实现也分开,但是没有必要,只要能正常运行就可以了;
以上便是文章的全部内容,感谢观看!