浅谈模板及模板推导
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">假设我们需要一个求和函数,我们可能会写成这样:</p>
<div style="text-align: left; margin-bottom: 10px;"><span style="color: green;">double</span> <span style="color: green;">Add</span><span style="color: green;">(</span><span style="color: green;">int</span> <span style="color: green;">a</span><span style="color: green;">,</span> <span style="color: green;">int</span> <span style="color: green;">b</span><span style="color: green;">){</span>
<span style="color: green;">return</span> <span style="color: green;">a</span> <span style="color: green;">+</span> <span style="color: green;">b</span><span style="color: green;">;</span>
<span style="color: green;">}</span>
</div>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">当用户传递给该函数两个整型实参时,函数正常运行。</p>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">但是当用户传递两个double类型,比如Add(2.5, 3.6),或者一个int一个double,比如Add(2, 3.6),或者更多其它类型的组合的时候,编译器便找不到相匹配的函数。</p>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">于是,我们不得不使用重载,将可能出现的情况一一列举:</p>
<div style="text-align: left; margin-bottom: 10px;"><span style="color: green;">double</span> <span style="color: green;">Add</span><span style="color: green;">(</span><span style="color: green;">int</span> <span style="color: green;">a</span><span style="color: green;">,</span> <span style="color: green;">int</span> <span style="color: green;">b</span><span style="color: green;">)</span>
<span style="color: green;">{</span>
<span style="color: green;">return</span> <span style="color: green;">a</span> <span style="color: green;">+</span> <span style="color: green;">b</span><span style="color: green;">;</span>
<span style="color: green;">}</span>
<span style="color: green;">double</span> <span style="color: green;">Add</span><span style="color: green;">(</span><span style="color: green;">double</span> <span style="color: green;">a</span><span style="color: green;">,</span> <span style="color: green;">double</span> <span style="color: green;">b</span><span style="color: green;">)</span>
<span style="color: green;">{</span>
<span style="color: green;">return</span> <span style="color: green;">a</span> <span style="color: green;">+</span> <span style="color: green;">b</span><span style="color: green;">;</span>
<span style="color: green;">}</span>
<span style="color: green;">double</span> <span style="color: green;">Add</span><span style="color: green;">(</span><span style="color: green;">int</span> <span style="color: green;">a</span><span style="color: green;">,</span> <span style="color: green;">double</span> <span style="color: green;">b</span><span style="color: green;">)</span>
<span style="color: green;">{</span>
<span style="color: green;">return</span> <span style="color: green;">a</span> <span style="color: green;">+</span> <span style="color: green;">b</span><span style="color: green;">;</span>
<span style="color: green;">}</span>
<span style="color: green;">double</span> <span style="color: green;">Add</span><span style="color: green;">(</span><span style="color: green;">double</span> <span style="color: green;">a</span><span style="color: green;">,</span> <span style="color: green;">int</span> <span style="color: green;">b</span><span style="color: green;">)</span>
<span style="color: green;">{</span>
<span style="color: green;">return</span> <span style="color: green;">a</span> <span style="color: green;">+</span> <span style="color: green;">b</span><span style="color: green;">;</span>
<span style="color: green;">}</span>
<span style="color: green;">...</span>
<span style="color: green;">...</span>
</div>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">我们发现,上面那么多的重载函数,除了参数的类型不同以外,其它的所有部分都是一样的。</p>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">那么有没有一种方法,可以代替我们进行这些廉价的体力劳动呢?</p>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">答案就是:模板</p>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">模板的一般形式如下</p>
<div style="text-align: left; margin-bottom: 10px;"><span style="color: green;">template</span><span style="color: green;"><</span><span style="color: green;">typename</span> <span style="color: green;">T</span><span style="color: green;">,</span> <span style="color: green;">typename</span> <span style="color: green;">U</span><span style="color: green;">></span> <span style="color: green;">// 定义了两种类型 T U
</span><span style="color: green;">double</span> <span style="color: green;">Add</span><span style="color: green;">(</span><span style="color: green;">T</span> <span style="color: green;">a</span><span style="color: green;">,</span> <span style="color: green;">U</span> <span style="color: green;">b</span><span style="color: green;">)</span> <span style="color: green;">// 使用类型 T U 分别定义了形参
</span><span style="color: green;">{</span>
<span style="color: green;">return</span> <span style="color: green;">a</span> <span style="color: green;">+</span> <span style="color: green;">b</span><span style="color: green;">;</span>
<span style="color: green;">}</span>
</div>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">其中template<>里面typename X的个数是可选的,可以是一个,也可以是多个。</p>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">模板是怎么实现自定义类型的呢?</p>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">具体的流程可以这样理解:</p>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">当我们在IDE写下这样的代码:</p>
<div style="text-align: left; margin-bottom: 10px;"><span style="color: green;">#include</span> <span style="color: green;"><iostream></span>
<span style="color: green;">template</span><span style="color: green;"><</span><span style="color: green;">typename</span> <span style="color: green;">T</span><span style="color: green;">,</span> <span style="color: green;">typename</span> <span style="color: green;">U</span><span style="color: green;">></span>
<span style="color: green;">double</span> <span style="color: green;">Add</span><span style="color: green;">(</span><span style="color: green;">T</span> <span style="color: green;">a</span><span style="color: green;">,</span> <span style="color: green;">U</span> <span style="color: green;">b</span><span style="color: green;">)</span>
<span style="color: green;">{</span>
<span style="color: green;">return</span> <span style="color: green;">a</span> <span style="color: green;">+</span> <span style="color: green;">b</span><span style="color: green;">;</span>
<span style="color: green;">}</span>
<span style="color: green;">int</span> <span style="color: green;">main</span><span style="color: green;">(</span><span style="color: green;">int</span> <span style="color: green;">argc</span><span style="color: green;">,</span> <span style="color: green;">char</span> <span style="color: green;">*</span><span style="color: green;">argv</span><span style="color: green;">[])</span>
<span style="color: green;">{</span>
<span style="color: green;">int</span> <span style="color: green;">a</span> <span style="color: green;">=</span> <span style="color: green;">1</span><span style="color: green;">;</span>
<span style="color: green;">int</span> <span style="color: green;">b</span> <span style="color: green;">=</span> <span style="color: green;">2</span><span style="color: green;">;</span>
<span style="color: green;">double</span> <span style="color: green;">c</span> <span style="color: green;">=</span> <span style="color: green;">3.6</span><span style="color: green;">;</span>
<span style="color: green;">Add</span><span style="color: green;">(</span><span style="color: green;">a</span><span style="color: green;">,</span> <span style="color: green;">b</span><span style="color: green;">);</span>
<span style="color: green;">Add</span><span style="color: green;">(</span><span style="color: green;">b</span><span style="color: green;">,</span><span style="color: green;">c</span><span style="color: green;">);</span>
<span style="color: green;">}</span>
</div>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">当我们点下编译按钮的时候,编译器所做的事情可以理解为一下两步。</p>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">第一遍编译器发现有一个模板函数Add(),然后编译器在整个代码里面找,在哪里调用了这个求和函数。最终编译器在mian找到了两处调用,编译器一看,这两处调用,一次是传了两个int,一次是传了一个int和一个double。</p>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">第一遍分析完了,编译器要做的第二步就是,将源码中的模板删掉,然后用具体的参数类型替换掉模板中的T和U类型,也就是说,上面的代码,经过编译器处理之后,就变成了这样:</p>
<div style="text-align: left; margin-bottom: 10px;"><span style="color: green;">#include</span> <span style="color: green;"><iostream></span>
<span style="color: green;">double</span> <span style="color: green;">Add</span><span style="color: green;">(</span><span style="color: green;">int</span> <span style="color: green;">a</span><span style="color: green;">,</span> <span style="color: green;">int</span> <span style="color: green;">b</span><span style="color: green;">)</span>
<span style="color: green;">{</span>
<span style="color: green;">return</span> <span style="color: green;">a</span> <span style="color: green;">+</span> <span style="color: green;">b</span><span style="color: green;">;</span>
<span style="color: green;">}</span>
<span style="color: green;">double</span> <span style="color: green;">Add</span><span style="color: green;">(</span><span style="color: green;">int</span> <span style="color: green;">a</span><span style="color: green;">,</span> <span style="color: green;">double</span> <span style="color: green;">b</span><span style="color: green;">)</span>
<span style="color: green;">{</span>
<span style="color: green;">return</span> <span style="color: green;">a</span> <span style="color: green;">+</span> <span style="color: green;">b</span><span style="color: green;">;</span>
<span style="color: green;">}</span>
<span style="color: green;">int</span> <span style="color: green;">main</span><span style="color: green;">(</span><span style="color: green;">int</span> <span style="color: green;">argc</span><span style="color: green;">,</span> <span style="color: green;">char</span> <span style="color: green;">*</span><span style="color: green;">argv</span><span style="color: green;">[])</span>
<span style="color: green;">{</span>
<span style="color: green;">int</span> <span style="color: green;">a</span> <span style="color: green;">=</span> <span style="color: green;">1</span><span style="color: green;">;</span>
<span style="color: green;">int</span> <span style="color: green;">b</span> <span style="color: green;">=</span> <span style="color: green;">2</span><span style="color: green;">;</span>
<span style="color: green;">double</span> <span style="color: green;">c</span> <span style="color: green;">=</span> <span style="color: green;">3.6</span><span style="color: green;">;</span>
<span style="color: green;">Add</span><span style="color: green;">(</span><span style="color: green;">a</span><span style="color: green;">,</span> <span style="color: green;">b</span><span style="color: green;">);</span>
<span style="color: green;">Add</span><span style="color: green;">(</span><span style="color: green;">b</span><span style="color: green;">,</span><span style="color: green;">c</span><span style="color: green;">);</span>
<span style="color: green;">}</span>
</div>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">最后,编译器将重写之后的代码再进行编译,所有的函数调用都可以找到相匹配的实现了。</p>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">简单来说,编译器做的事情有两件:第一个是找到模板并找到哪些地方调用了模板,第二个就是根据调用模板的实际类型替换掉模板,生成没有模板的代码。最后就可以再次编译运行了。</p>
<h2 style="text-align: left; margin-bottom: 10px;">模板推导</h2>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">模板推导就是根据传递给模板的实参类型,推导出应该生成的模板代码。</p>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">比如:</p>
<div style="text-align: left; margin-bottom: 10px;"><span style="color: green;">template</span><span style="color: green;"><</span><span style="color: green;">typename</span> <span style="color: green;">T</span><span style="color: green;">,</span> <span style="color: green;">typename</span> <span style="color: green;">U</span><span style="color: green;">></span> <span style="color: green;">// 定义了两种类型 T U
</span><span style="color: green;">double</span> <span style="color: green;">Add</span><span style="color: green;">(</span><span style="color: green;">T</span> <span style="color: green;">a</span><span style="color: green;">,</span> <span style="color: green;">U</span> <span style="color: green;">b</span><span style="color: green;">)</span> <span style="color: green;">// 使用类型 T U 分别定义了形参
</span><span style="color: green;">{</span>
<span style="color: green;">return</span> <span style="color: green;">a</span> <span style="color: green;">+</span> <span style="color: green;">b</span><span style="color: green;">;</span>
<span style="color: green;">}</span>
<span style="color: green;">Add</span><span style="color: green;">(</span><span style="color: green;">1</span><span style="color: green;">,</span><span style="color: green;">2</span><span style="color: green;">);</span> <span style="color: green;">// T被推导为int类型
</span>
</div>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">模板推导是在编译器期间做的事情,而推导的规则基本上是符合我们预料的情况。但是具体来说,可以分为三大类型:</p>按值传递的模板推导按引用传递的模板推导万能引用<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">本节主要介绍前面两点。</p>
<h2 style="text-align: left; margin-bottom: 10px;">按值传递</h2>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">按值传递的模板形式如下:</p>
<div style="text-align: left; margin-bottom: 10px;"><span style="color: green;">template</span><span style="color: green;"><</span><span style="color: green;">typename</span> <span style="color: green;">T</span><span style="color: green;">></span>
<span style="color: green;">ReturnType</span> <span style="color: green;">Function</span><span style="color: green;">(</span><span style="color: green;">T</span> <span style="color: green;">param</span><span style="color: green;">)</span>
<span style="color: green;">{</span>
<span style="color: green;">// 函数实现
</span><span style="color: green;">}</span>
</div>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">注意模板参数的形式,必须是T param的形式才是表达的按值推导。</p>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">因为按值传递的实质是对实参对象进行拷贝,得到实参的一个副本。所以,按值传递的时候,实参的常量性和引用性都会被忽略。</p>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">下面是几个模板推导的实例</p>
<div style="text-align: left; margin-bottom: 10px;"><span style="color: green;">#include</span> <span style="color: green;"><iostream></span><span style="color: green;">using</span> <span style="color: green;">namespace</span> <span style="color: green;">std</span><span style="color: green;">;</span>
<span style="color: green;">template</span><span style="color: green;"><</span><span style="color: green;">typename</span> <span style="color: green;">T</span><span style="color: green;">></span>
<span style="color: green;">void</span> <span style="color: green;">Function</span><span style="color: green;">(</span><span style="color: green;">T</span> <span style="color: green;">param</span><span style="color: green;">)</span>
<span style="color: green;">{</span>
<span style="color: green;">// 函数实现
</span><span style="color: green;">}</span>
<span style="color: green;">int</span> <span style="color: green;">main</span><span style="color: green;">(</span><span style="color: green;">int</span> <span style="color: green;">argc</span><span style="color: green;">,</span> <span style="color: green;">char</span> <span style="color: green;">*</span><span style="color: green;">argv</span><span style="color: green;">[])</span>
<span style="color: green;">{</span>
<span style="color: green;">int</span> <span style="color: green;">a</span> <span style="color: green;">=</span> <span style="color: green;">1</span><span style="color: green;">;</span>
<span style="color: green;">const</span> <span style="color: green;">int</span> <span style="color: green;">b</span> <span style="color: green;">=</span> <span style="color: green;">2</span><span style="color: green;">;</span>
<span style="color: green;">int</span> <span style="color: green;">&</span><span style="color: green;">ra</span> <span style="color: green;">=</span> <span style="color: green;">a</span><span style="color: green;">;</span>
<span style="color: green;">const</span> <span style="color: green;">int</span> <span style="color: green;">&</span><span style="color: green;">rb</span> <span style="color: green;">=</span> <span style="color: green;">b</span><span style="color: green;">;</span>
<span style="color: green;">int</span> <span style="color: green;">*</span><span style="color: green;">pa</span> <span style="color: green;">=</span> <span style="color: green;">&</span><span style="color: green;">a</span><span style="color: green;">;</span>
<span style="color: green;">const</span> <span style="color: green;">int</span> <span style="color: green;">*</span><span style="color: green;">pb</span> <span style="color: green;">=</span> <span style="color: green;">&</span><span style="color: green;">b</span><span style="color: green;">;</span>
<span style="color: green;">const</span> <span style="color: green;">int</span> <span style="color: green;">*</span><span style="color: green;">const</span> <span style="color: green;">cpb</span> <span style="color: green;">=</span> <span style="color: green;">&</span><span style="color: green;">b</span><span style="color: green;">;</span>
<span style="color: green;">Function</span><span style="color: green;">(</span><span style="color: green;">a</span><span style="color: green;">);</span> <span style="color: green;">// T 推导为int
</span>
<span style="color: green;">Function</span><span style="color: green;">(</span><span style="color: green;">b</span><span style="color: green;">);</span> <span style="color: green;">// T 推导为int,忽略b的常量性
</span>
<span style="color: green;">Function</span><span style="color: green;">(</span><span style="color: green;">ra</span><span style="color: green;">);</span> <span style="color: green;">// T 推导为int,忽略引用性
</span>
<span style="color: green;">Function</span><span style="color: green;">(</span><span style="color: green;">rb</span><span style="color: green;">);</span> <span style="color: green;">// T 推导为int,忽略常量性和引用性
</span>
<span style="color: green;">Function</span><span style="color: green;">(</span><span style="color: green;">pa</span><span style="color: green;">);</span> <span style="color: green;">// T 推导为int*,int*和int是不同的类型,
</span>
<span style="color: green;">Function</span><span style="color: green;">(</span><span style="color: green;">pb</span><span style="color: green;">);</span> <span style="color: green;">// T 推导为const int *
</span> <span style="color: green;">// 这里的const并不是pb本身的常量性,而是pb所指对象的常量性,所以得以保留
</span> <span style="color: green;">Function</span><span style="color: green;">(</span><span style="color: green;">cpb</span><span style="color: green;">);</span> <span style="color: green;">// T 推导为const int *,和上一条对比,cpb本身的常量性被忽略了
</span><span style="color: green;">}</span>
</div>
<h2 style="text-align: left; margin-bottom: 10px;">按引用传递</h2>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">如果你想要模板推导为引用类型,那么你的模板应该是这样的:</p>
<div style="text-align: left; margin-bottom: 10px;"><span style="color: green;">template</span><span style="color: green;"><</span><span style="color: green;">typename</span> <span style="color: green;">T</span><span style="color: green;">></span>
<span style="color: green;">ReturnType</span> <span style="color: green;">Function</span><span style="color: green;">(</span><span style="color: green;">T</span><span style="color: green;">&</span> <span style="color: green;">param</span><span style="color: green;">)</span>
<span style="color: green;">{</span>
<span style="color: green;">// 函数实现
</span><span style="color: green;">}</span>
</div>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">以下是几个实例:</p>
<div style="text-align: left; margin-bottom: 10px;"><span style="color: green;">#include</span> <span style="color: green;"><iostream></span><span style="color: green;">using</span> <span style="color: green;">namespace</span> <span style="color: green;">std</span><span style="color: green;">;</span>
<span style="color: green;">template</span><span style="color: green;"><</span><span style="color: green;">typename</span> <span style="color: green;">T</span><span style="color: green;">></span>
<span style="color: green;">void</span> <span style="color: green;">Function</span><span style="color: green;">(</span><span style="color: green;">T</span><span style="color: green;">&</span> <span style="color: green;">param</span><span style="color: green;">)</span> <span style="color: green;">// 传递引用的模板
</span><span style="color: green;">{</span>
<span style="color: green;">// 函数实现
</span><span style="color: green;">}</span>
<span style="color: green;">int</span> <span style="color: green;">main</span><span style="color: green;">(</span><span style="color: green;">int</span> <span style="color: green;">argc</span><span style="color: green;">,</span> <span style="color: green;">char</span> <span style="color: green;">*</span><span style="color: green;">argv</span><span style="color: green;">[])</span>
<span style="color: green;">{</span>
<span style="color: green;">int</span> <span style="color: green;">a</span> <span style="color: green;">=</span> <span style="color: green;">1</span><span style="color: green;">;</span>
<span style="color: green;">const</span> <span style="color: green;">int</span> <span style="color: green;">b</span> <span style="color: green;">=</span> <span style="color: green;">2</span><span style="color: green;">;</span>
<span style="color: green;">int</span> <span style="color: green;">&</span><span style="color: green;">ra</span> <span style="color: green;">=</span> <span style="color: green;">a</span><span style="color: green;">;</span>
<span style="color: green;">const</span> <span style="color: green;">int</span> <span style="color: green;">&</span><span style="color: green;">rb</span> <span style="color: green;">=</span> <span style="color: green;">b</span><span style="color: green;">;</span>
<span style="color: green;">int</span> <span style="color: green;">*</span><span style="color: green;">pa</span> <span style="color: green;">=</span> <span style="color: green;">&</span><span style="color: green;">a</span><span style="color: green;">;</span>
<span style="color: green;">const</span> <span style="color: green;">int</span> <span style="color: green;">*</span><span style="color: green;">pb</span> <span style="color: green;">=</span> <span style="color: green;">&</span><span style="color: green;">b</span><span style="color: green;">;</span>
<span style="color: green;">const</span> <span style="color: green;">int</span> <span style="color: green;">*</span><span style="color: green;">const</span> <span style="color: green;">cpb</span> <span style="color: green;">=</span> <span style="color: green;">&</span><span style="color: green;">b</span><span style="color: green;">;</span>
<span style="color: green;">Function</span><span style="color: green;">(</span><span style="color: green;">a</span><span style="color: green;">);</span> <span style="color: green;">// T 推导为int
</span>
<span style="color: green;">Function</span><span style="color: green;">(</span><span style="color: green;">b</span><span style="color: green;">);</span> <span style="color: green;">// T 推导为const int
</span>
<span style="color: green;">Function</span><span style="color: green;">(</span><span style="color: green;">ra</span><span style="color: green;">);</span> <span style="color: green;">// T 推导为int,忽略ra引用性
</span>
<span style="color: green;">Function</span><span style="color: green;">(</span><span style="color: green;">rb</span><span style="color: green;">);</span> <span style="color: green;">// T 推导为const int,忽略rb引用性
</span>
<span style="color: green;">Function</span><span style="color: green;">(</span><span style="color: green;">pa</span><span style="color: green;">);</span> <span style="color: green;">// T 推导为int*,
</span>
<span style="color: green;">Function</span><span style="color: green;">(</span><span style="color: green;">pb</span><span style="color: green;">);</span> <span style="color: green;">// T 推导为const int *
</span>
<span style="color: green;">Function</span><span style="color: green;">(</span><span style="color: green;">cpb</span><span style="color: green;">);</span> <span style="color: green;">// T 推导为const int *const,和上一条对比,cpb本身的常量性被忽略了
</span><span style="color: green;">}</span>
</div>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">以上推导的规则就是,如果传递进去的是一个值,那么就生成对该值类型的引用模板,因为引用参数可以接受值类型参数。如果传递进去的是一个引用类型,那么模板将忽略实参的引用性(因为模板里已经明确写了T&,所以实参的引用性可以忽略不看),然后再进行推导。比如,传递进去是rb,rb的类型是const int &,忽略引用性就剩下const int,这就是 T 被推导的类型了。</p>
<h2 style="text-align: left; margin-bottom: 10px;">关于推导数组类型和函数指针类型</h2>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">对于这两种,不作更多的解释。大家记住就好,模板推导这东西,本身就没啥固定的规则可言,基本的原则就是要符合用户的预期。</p>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">数组模板:</p>
<div style="text-align: left; margin-bottom: 10px;"><span style="color: green;">#include</span> <span style="color: green;"><iostream></span><span style="color: green;">using</span> <span style="color: green;">namespace</span> <span style="color: green;">std</span><span style="color: green;">;</span>
<span style="color: green;">template</span><span style="color: green;"><</span><span style="color: green;">typename</span> <span style="color: green;">T</span><span style="color: green;">></span>
<span style="color: green;">void</span> <span style="color: green;">ArrayPattern1</span><span style="color: green;">(</span><span style="color: green;">T</span><span style="color: green;">&</span> <span style="color: green;">param</span><span style="color: green;">)</span> <span style="color: green;">// 数组模板
</span><span style="color: green;">{</span>
<span style="color: green;">// ...
</span><span style="color: green;">}</span>
<span style="color: green;">template</span><span style="color: green;"><</span><span style="color: green;">typename</span> <span style="color: green;">T</span><span style="color: green;">,</span> <span style="color: green;">size_t</span> <span style="color: green;">N</span><span style="color: green;">></span>
<span style="color: green;">void</span> <span style="color: green;">ArrayPattern2</span><span style="color: green;">(</span><span style="color: green;">T</span> <span style="color: green;">(</span><span style="color: green;">&</span><span style="color: green;">param</span><span style="color: green;">)[</span><span style="color: green;">N</span><span style="color: green;">])</span> <span style="color: green;">//数组模板,并推导出数组元素个数
</span><span style="color: green;">{</span>
<span style="color: green;">// ...
</span><span style="color: green;">}</span>
<span style="color: green;">template</span><span style="color: green;"><</span><span style="color: green;">typename</span> <span style="color: green;">T</span><span style="color: green;">></span>
<span style="color: green;">void</span> <span style="color: green;">PrintType</span><span style="color: green;">(</span><span style="color: green;">T</span> <span style="color: green;">param</span><span style="color: green;">)</span>
<span style="color: green;">{</span>
<span style="color: green;">}</span>
<span style="color: green;">int</span> <span style="color: green;">main</span><span style="color: green;">(</span><span style="color: green;">int</span> <span style="color: green;">argc</span><span style="color: green;">,</span> <span style="color: green;">char</span> <span style="color: green;">*</span><span style="color: green;">argv</span><span style="color: green;">[])</span>
<span style="color: green;">{</span>
<span style="color: green;">int</span> <span style="color: green;">a</span><span style="color: green;">[</span><span style="color: green;">10</span><span style="color: green;">]{</span> <span style="color: green;">0</span> <span style="color: green;">};</span>
<span style="color: green;">ArrayPattern1</span><span style="color: green;">(</span><span style="color: green;">a</span><span style="color: green;">);</span> <span style="color: green;">// T的类型为 int , param的类型为 int(&)
</span> <span style="color: green;">ArrayPattern2</span><span style="color: green;">(</span><span style="color: green;">a</span><span style="color: green;">);</span> <span style="color: green;">// T的类型为 int, param的类型为 int(&)
</span> <span style="color: green;">PrintType</span><span style="color: green;">(</span><span style="color: green;">a</span><span style="color: green;">);</span> <span style="color: green;">// 按值传递,a退化为指针,丢失了数组元素个数的信息
</span><span style="color: green;">}</span>
</div>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">函数模板</p>
<p style="font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;">函数模板既可以按值传递,也可以按引用传递。效果是一样的。</p>
页:
[1]