小学生学C++编程语法知识(C++模板(Template)详解)

📅 2026/8/1 2:49:42 👁️ 阅读次数 📝 编程学习
小学生学C++编程语法知识(C++模板(Template)详解)


C++模板(Template)详解——给小学生的“魔法公式”


同学们,今天我们学习一个在C++编程、STL标准库、算法竞赛中非常重要的知识:模板(Template)


你平时写代码,会经常看到:

vector<int> a; sort(a.begin(),a.end());

或者:

pair<int,int> p;

甚至:

priority_queue<int> q;

这里面的:

<int>

其实就是模板参数


那么:

为什么一个vector既可以装int,又可以装string?

为什么sort既可以排序整数,又可以排序字符串?

C++到底是怎么做到的?

这就是今天要解决的问题。


一、为什么需要模板?

1. 一个现实问题

假设我们要写一个交换两个数字的函数。

比如:

交换两个整数:

void swap(int &a,int &b) { int t=a; a=b; b=t; }

使用:

int x=10; int y=20; swap(x,y);

很好。


但是后来我们想交换:

double类型

double a=1.2; double b=3.5;

怎么办?


重新写:

void swap(double &a,double &b) { double t=a; a=b; b=t; }

发现:

代码完全一样!

区别只有:

int

换成:

double

后来还有:

string char long long

是不是每一种都写一个?

太麻烦了。


二、模板的思想:写一个万能版本

程序员想:

能不能先不告诉计算机是什么类型?

比如:

"以后你告诉我交换什么,我自动生成对应代码。"

于是出现:

函数模板

写法:

template<typename T> void mySwap(T &a,T &b) { T temp=a; a=b; b=temp; }

这里:

T

就是一个占位符。


你可以理解成:

一个空盒子。

现在:

T还不知道是什么。


调用:

情况1:交换int

int a=10; int b=20; mySwap(a,b);

编译器发现:

a,b是int。

于是:

把模板变成:

void mySwap(int &a,int &b) { int temp=a; a=b; b=temp; }

情况2:交换double

double x=1.1; double y=2.2; mySwap(x,y);

编译器生成:

void mySwap(double &a,double &b) { double temp=a; a=b; b=temp; }

所以:

一个模板:

template<typename T>

可以生成很多函数。


三、模板底层到底如何实现?

这是重点。

很多初学者认为:

模板是不是运行的时候判断类型?

不是!

C++模板:

不是运行时技术

而是:

编译时期生成代码

也叫:

模板实例化(Template Instantiation)


例如:

我们写:

template<typename T> T add(T a,T b) { return a+b; }

调用:

cout<<add(3,5); cout<<add(1.5,2.5);

编译器看到以后:

偷偷生成两个函数:

第一个:

int add(int a,int b) { return a+b; }

第二个:

double add(double a,double b) { return a+b; }

最后真正运行的时候:

程序里面根本没有模板!

只有:

add(int)

和:

add(double)

可以画成:

模板代码 template<T> | | ↓ 编译器加工 | ---------------------- | | int版本 double版本 | ↓ 最终机器代码

四、为什么模板运行速度快?

因为:

模板是在编译阶段展开。

运行时:

没有:

判断类型 if(int) else(double)

所以:

速度和普通函数一样。

例如:

vector

实际上:

编译器生成:

整数数组管理代码

vector

生成:

double数组管理代码

没有额外损耗。


五、类模板

除了函数可以模板化。

类也可以。

例如:

我们想写一个盒子。

普通类:

class Box { public: int value; };

只能装:

int

如果想装:

double string

怎么办?


使用:

类模板

template<typename T> class Box { public: T value; };

现在:

Box<int> a; Box<double> b; Box<string> c;

三个盒子:

分别变成:

Box<int> Box<double> Box<string>

六、STL为什么全部使用模板?

这是竞赛中重要的地方。

1. vector

你写:

vector<int> a;

实际上:

vector是模板:

template<typename T> class vector { T *data; };

所以:

vector<int>

变成:

整数数组管理器

如果:

vector<string>

变成:

字符串数组管理器

七、sort为什么可以排序各种类型?

你有没有想过:

sort(a,a+n);

为什么:

int可以:

5 2 9 1

string也可以:

apple banana cat

因为:

sort也是模板。

类似:

template<class Iterator> void sort(Iterator begin,Iterator end) { }

编译器根据你的数据:

自动生成:

整数排序版本。

字符串排序版本。


八、typename 和 class 有什么区别?

经常看到:

template<typename T>

也看到:

template<class T>

其实这里:

没有区别。

例如:

template<class T> void fun(T x) { }

等价:

template<typename T> void fun(T x) { }

只是:

现代C++更推荐:

typename

因为:

更能表达:

"这里是一个类型"


九、模板和普通函数有什么区别?

比较一下:

普通函数

int max(int a,int b) { return a>b?a:b; }

只能:

int


模板:

template<typename T> T myMax(T a,T b) { return a>b?a:b; }

可以:

myMax(3,5); myMax(2.5,8.1); myMax('a','z');

十、模板的缺点

模板很强,但是也有问题。

1. 编译时间变长

因为:

一个模板可能生成很多代码。

例如:

vector<int> vector<double> vector<string> vector<long long>

编译器都要生成。


2. 错误信息很复杂

例如:

模板错误:

可能出现:

几十行报错。

初学者看到:

std::__cxx11...

很害怕。

其实:

通常只是:

类型不匹配。


十一、信奥竞赛中什么时候需要模板?

小学阶段:

理解:

⭐⭐⭐⭐

使用:

⭐⭐

中学竞赛:

大量使用。

例如:

STL

vector queue stack set map priority_queue sort

全部依赖模板。


十二、给同学们的总结

模板是什么?

一句话:

模板就是“代码的万能设计图”。

比如:

普通代码:

一个盒子 只能装苹果

模板:

一个魔法盒子 你放苹果 它变苹果盒 你放香蕉 它变香蕉盒

模板底层原理:

记住一句:

C++模板不是运行时变化,而是在编译时复制生成不同版本代码。

过程:

模板 ↓ 编译器看到使用方式 ↓ 自动生成对应代码 ↓ 编译成机器语言 ↓ 运行

以后学习:

vector set map priority_queue sort

不要认为:

"这是C++给我的工具"

而要知道:

它们背后都是:

高级程序员利用模板技术,把通用算法提前设计好,然后让编译器自动生成适合你的版本。

这也是C++相比很多语言强大的核心原因之一。你学习模板,本质是在学习:

如何写出“一个代码,适应无限场景”的能力。