目录
一直想写一点C++稍微进阶学习的内容,趁着这一小段空闲时间,写一点吧。
模板函数
为什么要有模板
记住两句话就够了:
1:类型参数化(本质!!!)
2:将与类型无关的底层逻辑抽象出来
举个例子
void test_swap(int &a,int &b)
{
int c = a;
a = b;
b = c;
}
这是一个交换函数,函数的参数是a和b,参数的类型是int类型
现在的话我们不满足于简单的变量参数,我们想把变量的类型也当做参数来处理,这样我们想传入什么类型的变量都可以进行交换了,比如字符类型char。
模板函数的简单例子:
template <typename T> //typename关键字是为了告诉编译器这是模板,对其进行特殊处理,T就是参数类型的变量,也可以使用class
void test_swap1(T &a, T &b){
T c = a;
a = b;
b = c;
}
这样我们就把“交换”这个底层的逻辑给抽象出来了,让“交换”这个操作变得与类型无关。
以上,就解释了模板函数的存在必要性与原因。
模板函数的使用
int var1 = 2;
int var2 =3;
test_swap1<int>(var1, var2);
相当简单,与正常函数使用不同的地方就是使用尖括号提前给函数传入一个类型参数,学名叫:类型的参数化列表。
这是模板函数的显示调用,那么如果我们不给模板函数提前传入类型参数,可不可以呢?
答案是:可以也不可以
可以的情况是模板会自动识别类型,前提是传入的参数保持一致
test_swap1(var1, var2);//这样是可以运行的
但是这样就违反了模板函数的规则:
int var1 = 2;
char var2 = 'a';
test_swap1(var1, var2);
你这样写的话程序也会提示错误,不用太担心。
三个小坑
1:模板函数定义的类型参数必须要用
template <class T,typename T2>
void test_swap1(T &a, T &b)
{
T c = a;
a = b;
b = c;
}
这样是会出错的,注意这里和函数的普通参数是不一样的,对于函数的普通参数,传入一个a一个b,只用a不用b是完全可以的,但是对于泛型编程的类型参数是不行的,所有定义的类型参数必须使用。
2:模板函数内部逻辑的改动,需要重新进行编译
简单的改动:
template <typename T>
void test_swap1(T &a, T &b)
{
a = b;
T d = a+b;
b = d;
}
需要重新编译与编译器怎样实现模板函数有很大关系,后面会捎带讲到。(模板机制的本质)
3:注意函数的返回类型是不可以参数化的哦~~
简单的排序算法泛型编程
#include<iostream>
using namespace std;
// T1类型为int,T2类型为unsigned int
template<typename T1, typename T2>
int template_sort(T1 m_array[],T2 len)
{
if (m_array == NULL)
{
return -1;
}
for (T2 i=0;i<len;i++)
{
for (T2 j=i+1;j<len;j++)
{
if (m_array[i]>m_array[j])
{
T1 temp = m_array[i];
m_array[i] = m_array[j];
m_array[j] = temp;
}
}
}
return 0;
}
template<typename T1, typename T2>
int template_print(T1 m_array[], T2 len)
{
if (m_array == NULL)
{
return -1;
}
for (T2 i = 0; i<len; i++)
{
cout << m_array[i] << " ";
}
return 0;
}
int main()
{
int i_array[] = { 0,2,5,1,2,85,9,6,2 };
char c_array[] = "asdnba126sjhci123sda";
template_sort(i_array, sizeof(i_array) / sizeof(i_array[0]));
template_sort(c_array, sizeof(c_array) / sizeof(c_array[0]));
template_print(i_array, sizeof(i_array) / sizeof(i_array[0]));
template_print(c_array, sizeof(c_array) / sizeof(c_array[0]));
return 0;
}