16理解函数模板
理解函数模板
模板的意义:对函数类型可以做修改
- 函数模板:bool compare(T a, T b)
 - 模板实例化:定义一个模板参数类型,进行一次函数的实例化
 - 模板函数:一个函数模板的实例化就是一个模板函数
 - 模板类型参数:T
 - 模板非类型参数:
 - 模板的实参推演:根据实参反推模板参数类型
 - 模板的特例化:为函数模板的特殊参数类型进行特殊设置
 - 对于某些类型来说,依赖模板的函数逻辑是有问题的。需要模板的特例化,特例化不是编译器提供的,而是用户提供的一种实例化方法,
 - 函数模板 模板的特例化 非模板(普通)函数的重载关系:如下例三个字符串的compare函数,一般优先调用非模板函数,如果非模板函数不存在,才会调用特例化模板函数或模板函数。
 
#include <iostream>
#include <cstring>
using namespace std;
template<typename T> //定义一个模板类型参数列表,也可以定义为类
bool compare(T a, T b) { //compare是一个函数模板
	cout << "template" << endl;
	return a > b;
}
template<> //模板的特例化:针对compare函数模板,提供一个给const char*的特例化版本
bool compare(const char *a, const char *b) { //compare是一个函数模板
	cout << "str template" << endl;
	return strcmp(a, b) > 0;
}
//compare是一个函数模板
//在函数调用点,编译器用用户指定的类型,从原模版实例化一份函数代码
//从函数模板实例化出来的函数为模板函数,如下
//符号表会依据函数名和参数类型为每个模板函数加入新符号,模板函数才是真正被编译的函数,而函数模板不是
//bool compare<int>(int a, int b) { 
//	cout << "template" << endl;
//	return a > b;
//}
//bool compare<double>(double a, double b) { 
//	cout << "template" << endl;
//	return a > b;
//}
int main() {
	//函数的调用点
	compare<int>(10, 20);
	compare<double>(10.0, 20.0);
	compare(10, 20); //函数模板的实参推演:根据用户传入的实参类型,反推出模板所使用的类型参数
	//第二次使用compare<int>时不需要再次产生模板函数,直接调用第一次产生的函数即可
	//compare(10, 20.0); //报错,无法确定模板参数类型
    compare("aa", "bb"); //可以执行,默认实参自动推演为const char*,从而比较两个指针地址的大小。
    //如果进行字符串的字典比较,如何?
	return 0;
}
- 如果将函数模板定义在另一个文件中定义,会出现问题。因为模板本身不会编译,模板函数才会编译。如果A文件中调用了B文件中的模板函数,事实上在编译汇编阶段,B文件并不会编译产生A所需的模板函数,符号表中也不会产生对应符号,因此在链接阶段,A文件所需使用的几个*UND*函数符号无法在B中找到。不过,B中定义的普通函数和特例化模板函数在A中是可以被看到的。因此模板源代码一般都放在头文件中,在源文件中#include直接展开。
 - 如果在调用之前,声明函数模板对应类型的模板函数,也可以避免上述情况,一般不这样。
 
模板的非类型参数
template<typename T, int SIZE> 
//模板的模板参数列表
// //SIZE为非类型形参,非类型形参在模板的内部是常量,且只能是整型,指针和引用,在编译阶段确定值
//将SIZE设置为模板非类型形参,间接不需要函数传参
void sort(T* arr) {
	for (int i = 0; i < SIZE - 1; i++) {
		for (int j = 0; j < SIZE - 1 - i; j++) {
			if (arr[j] > arr[j + 1]) {
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = arr[j];
			}
		}
	}
}
int main() {
	char arr[] = { 1, 2, 3, 4, 5, 6 };
	const int size = sizeof(arr) / sizeof(int);
	sort<char, size>(arr);
}

                
            
        
浙公网安备 33010602011771号