1 前言

在学习 C++ template function (模板函数)时,用之前的cmake编译无法通过,遂对其进行了一下学习。主要参考了《C++ Primer》这本书。

2 模板函数的基本使用

模板函数是为了解决C++编程中仅针对数据类型不同而提出的一种泛型编程方法,例如比较大小的函数:

1
2
3
4
5
6
7
8
9
10
11
int compare(int v1, int v2) {
if (v1 < v2) return 1;
if (v1 > v2) return -1;
return 0;
}

int compare(double v1, double v2) {
if (v1 < v2) return 1;
if (v1 > v2) return -1;
return 0;
}

对于上述两个函数,只有传入的参数类型不一致,函数主体内容完全一致,因此,可以用函数模板来实现。

1
2
3
4
5
6
template <typename T>
int compare(const T & v1, const T & v2) {
if (v1 < v2) return 1;
if (v1 > v2) return -1;
return 0;
}

两点注意:

  • template <typename T>后不加分号
  • typename也可以写为class,没有区别

3 模板函数编译

模板函数只是提供了一类方法,编译时编译器会自动推导对应类型。工程目录如下:

1
2
3
4
5
6
7
8
9
10
.
├── build
├── CMakeLists.txt
├── include
│   ├── compare.tpp
│   └── demo_template.h
├── main.cpp
├── readme.md
└── src
└── demo_template.cpp

点击查看`demo_template.h`
1
2
3
4
5
6
7
8
9
10
#ifndef _DEMO_TEMPLATE_
#define _DEMO_TEMPLATE_
#include <iostream>
#include "compare.tpp"

using namespace std;

void fun();

#endif
点击查看`demo_template.cpp`
1
2
3
4
5
#include "demo_template.h"

void fun() {
cout << "Have a fun day~" << endl;
}
点击查看`compare.tpp`
1
2
3
4
5
6
7
8
9
10
#include <iostream>
using namespace std;

template <typename T>
int compare(const T & v1, const T & v2){
cout << "Here is template compare function." << endl;
if (v1 < v2) return 1;
if (v1 > v2) return -1;
return 0;
}
点击查看`CMakeLists.txt`
1
2
3
4
5
cmake_minimum_required(VERSION 2.8)
project(demo_template)
include_directories("include")
aux_source_directory(src SRC_ALL_FILES)
add_executable(${PROJECT_NAME} main.cpp ${SRC_ALL_FILES})
点击查看`main.cpp`
1
2
3
4
5
6
7
8
9
10
#include <vector>
#include "demo_template.h"

int main() {
cout << compare<int>(3, 0) << endl;
vector<int> vec1{1, 2, 3}, vec2{4, 5, 6};
cout << compare(vec1, vec2) << endl;
fun();
return 0;
}

编译及运行:

1
2
3
4
cd build
cmake ..
make
./demo_template

运行结果如下:

1
2
3
4
5
Here is template compare function.
-1
Here is template compare function.
1
Have a fun day~

特别注意:
模板函数不能像普通函数fun一样,在头文件demo_template.h里声明,再在实现的源码文件demo_template.cpp里写实现,这样编译的时候会报错,找不到具体的实例泛化。为此,可以采用的方式是:

  • 在头文件demo_template.h里直接写模板函数。
  • 或另写一个文件compare.tpp用来放模板,再在头文件中引用。