﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-jasper-文章分类-c++学习</title><link>http://www.cppblog.com/jasper/category/13069.html</link><description>jasper c++</description><language>zh-cn</language><lastBuildDate>Wed, 10 Feb 2010 15:20:38 GMT</lastBuildDate><pubDate>Wed, 10 Feb 2010 15:20:38 GMT</pubDate><ttl>60</ttl><item><title>显式模板实参</title><link>http://www.cppblog.com/jasper/articles/107261.html</link><dc:creator>jasper</dc:creator><author>jasper</author><pubDate>Fri, 05 Feb 2010 07:59:00 GMT</pubDate><guid>http://www.cppblog.com/jasper/articles/107261.html</guid><wfw:comment>http://www.cppblog.com/jasper/comments/107261.html</wfw:comment><comments>http://www.cppblog.com/jasper/articles/107261.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jasper/comments/commentRss/107261.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jasper/services/trackbacks/107261.html</trackback:ping><description><![CDATA[显式模板实参<br><br>一.在一些情况下编译器不可能推演出模板的实参的类型。如果模板实参推演过程为同一模板实参推演<br>出两个不同的类型，则编译器会给出一个错误，支持模板实参推演失败。<br>这种情况下，我们需要改变模板实参推演机制，并使用显式指定，模板实参被显式指定在逗号的列<br>表中，用尖括号括起来。<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">#include</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>template&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;min5(T,T){</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;T;}<br>unsigned&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;ui;<br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">min5(ui,12);&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">错误&nbsp;,同一个模板两个不同类型参数,必须使用显式模板实参如下：</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;min5</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">unsigned&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">(ui,</span><span style="COLOR: #000000">12</span><span style="COLOR: #000000">);</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">此时模板实例化的函数是：min5(unsigned&nbsp;int,unsigned&nbsp;int)</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}</span></div>
<br>
<p>分析：<br>1.显式模板实参min5&lt;unsigned int&gt;(ui,12) 参数类型被固定为unsigned.不需要推演模板实参了，且<br>实例化后，int型的&#8220;12&#8221; 可以通过有序标准转换成类型unsigned int（隐式类型转换）.<br>2.调用min5(ui,12);时，模板必须经过推演模板实参，推演ui时就确认了模板类型为min5(unsigned int,unsigned int)；<br>但是int型&#8220;12&#8221;，不是unsigned int ，所以程序不会通过转型，直接提示参数类型不一致。</p>
<p><br>显式模板参数还为其他的程序设计问题提供了方案。<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">template&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;T1,&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;T2,&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;T3</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;T1&nbsp;sum(T2,&nbsp;T3);<br><br><br>typedef&nbsp;unsigned&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;ui_type;<br>ui_type&nbsp;calc(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;ch,ui_type&nbsp;ui){<br>&nbsp;&nbsp;&nbsp;&nbsp;ui_type&nbsp;loc1</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">sum(ch,ui);</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">错误：T1不能被推演处理。<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">模板实参被显式指定</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;ui_type&nbsp;loc2</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">sum</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">ui_type,</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">,ui_type</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">(ch,ui);</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">实例化&nbsp;ui_type&nbsp;sum(ui_type,char,ui_type)<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">T2，T3通过推演（即省略了尾部参数），返回类型T1通过指定ui_type</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;ui_type&nbsp;loc3</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">sum</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">ui_type</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">(ch,ui);</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">实例化&nbsp;ui_type&nbsp;sum(ui_type,char,ui_type)<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">注意：只能通过省略模板参数列表的尾部参数。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;ui_type&nbsp;loc4</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">sum</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">ui_type,&nbsp;,ui_type</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">(ch,ui);</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">错误：模板推演不出来参数，只能省略模板参数列表尾部。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">}<br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main(){<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}</span></div>
<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008000">//</span><span style="COLOR: #008000">sum()实例地址被取出，并作为manipulate()调用的实参被传递。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"><br><br>#include</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>template&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;T1,</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;T2,</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;T3</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>T1&nbsp;sum(T2&nbsp;op1,T3&nbsp;op2){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T1&nbsp;a;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;a;<br>}<br></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;manipulate(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pf)(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">,</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">)&nbsp;){}<br></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;manipulate(</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pf)(</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">,</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">)&nbsp;){}<br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;manipulate(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">sum);</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">错误：产生二义性</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;manipulate(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">sum</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">,</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">,</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">);</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">显式指定了实例double&nbsp;sum(float,float);</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}</span></div>
<br>显式模板实参应该只被用于解决二义性，或者模板实参不能推演出来上下文中使用模板实例。<br>建议在可能的时候省略显示模板实参。 
<img src ="http://www.cppblog.com/jasper/aggbug/107261.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jasper/" target="_blank">jasper</a> 2010-02-05 15:59 <a href="http://www.cppblog.com/jasper/articles/107261.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>