什么是模板:模板允许你定义一个可以根据你的用途进行编译的模板(有意义下)。
故所谓模板,就是让编译器基于DIY的规则去为你写代码
🍅函数的模板(对形参)void Print(int temp) {
cout << temp;
}
void Print(string temp) {
cout << temp;
}
void Print(double temp) {
cout << temp;
}
int main() {
Print(1);
Print("hello");
Print(5.5);
//如果要用一个函数输出三个类型不同的东西,则要手动定义三个不同重载函数
//这其实就是一种复制粘贴就可以完成的 *** 作
}
为了减少复制粘贴的 *** 作,则要用模板
💡💡语法是:在返回类型之前,写上template
template<typename T> void Print(T temp) {
//把类型改成模板类型的名字如T就可以了
cout << temp;
}
//简洁无比,爽到
int main() {
Print(1);
Print("hello");
Print(5.5);
}
首先,通过template
定义,则说明如下的定义是一个模板,它会在编译期被评估,所以template
后面的函数其实不是一个实际的代码,只有当我们实际调用时,模板函数才会基于传递的参数来真的创建
template<typename T> void Print(T temp) {
cout << temp;
}
int main() {
return 0;
}
💡如果像上面甚至没有调用模板函数,则上面的模板函数就没有真正存在过!,只有当真正调用函数的时候才会被实际创建
💡💡然后对于模板参数如
template<typename T> void Print(T temp) {
cout << temp;
}
int main() {
Print(96);//这里其实是隐式的传递信息给模板,可读性不高
Print<int>(96);//可以显示的定义模板参数,声明函数接受的形参的类型!!!
Print<char>(96);//输出的可以是数字,也可以是字符!这样的 *** 纵性强了很多!!!
}
这里其实也可以用class
来代替typename
template<class T> void Print() = template<typename T> void Print();
但还是用typename
表达的意思更清楚一点,因为看到class
就想类去了,而这里表达的意思其实只是类型名字,而不是类
传递数字给模板,来指定要生成的类
//不仅仅是typename!
template<int N> class Array {
private:
//在栈上分配一个数组,而为了知道它的大小,要用模板传一个数字N过来
int m_Array[N];
};
int main() {
Array<5> array;//用尖括号给模板传递构造的规则。
惊了,看起来尖括号就是对模板进行 *** 作的好东西
}
然后可以和上面的知识进行结合,可以传多个规则给模板,用逗号隔开就行
//可以传类型,也可以传数字,功能太强大了
//两个模板参数:类型和大小
template<typename T, int size> class Array {
private:
T m_Array[size];//直接把数组完全DIY化了
};
int main() {
Array<int, 5> array;//感觉和vector等容器的定义非常像了,其实vector在库里的实质就是模板吧
}
🍅模板要在何时使用呢?(Cherno的经验之谈)
模板可以代替很多情况下的函数重载,比函数重载简洁,可读性高,为什么不用呢?
但也正因为模板可以DIY的太多了,很容易让人走火入魔写成一个元语言。
这种复杂化的模板的可读性将会是一场噩梦。
因为当模板越来越复杂的时候,可能除了作者以外没有人会知道这些模板是在干什么(所以在很多公司,其实是完全禁止使用模板的)
所以用模板要掌握一个度,不能滥用。
适当DIY有益延长个人寿命(自己写的舒服了),过度DIY降低团队寿命(团队无了)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)