⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 index.html

📁 《Big C++ 》Third Edition电子书和代码全集-Part1
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<!--	-*-html-*-
	$Source: /usr/local/cvsroot/BigC++/22/index.html,v $
	$Revision: 1.4 $
	Big C++, chptr 22
	editor: cols=80, tabstop=2

	(c) 2005 John Wiley & Sons
	Kurt Schmidt, kschmidt@cs.drexel.edu

	NOTES
	- 3 spaces are used for each indent in examples

	REVISIONS:
		$Log: index.html,v $
		Revision 1.4  2004/04/20 22:03:00  kurt
		Made slides smaller (view %150, on 1024x768 display)
		
		Revision 1.3  2004/02/23 16:21:58  kurt
		pared verbage
		
		Revision 1.2  2004/02/03 03:02:08  kurt
		Pared language, split slides
		
		Revision 1.1  2004/01/24 21:01:13  kurt
		Creation
		
-->

<html>

<head>
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  <meta name="Copyright" content="2005 John Wiley & Sons">
  <meta name="Author" content="Kurt Schmidt">
	<script language="JavaScript" src="./config.js"></script>
	<script language="JavaScript" src="./pageFormat.js"></script>
	<script><!-- // Set title on page
		title()
	//--></script>
</head>

<body>

<hr><h2><font color="#009999" size="+3">Chapter 22 - Templates</font></h2>
<font size="+1">

<script><!-- // Set title on page
	image( "cover.png" )
//--></script>

</font>

<hr><h2><font color="#009999" size="+2">Chapter Goals</font></h2>
</font>
<hr noshade size="4" color="#009999">
<font size="+1">

<ul>
	<li>To be able to use and define template functions</li>
	<li>To learn how to use and define template classes</li>
	<li>To understand the relationship between template functions and classes
		and ordinary functions and classes</li>
	<li>To learn how to use <tt>typedef</tt> statements to create alias names
		for long type names</li>
	<li>To understand the interactions between template classes, inheritance,
		and static data fields</li>
	<li>To learn how policy can be established by the selection of template
		arguments</li>
</ul>

</font>

<hr><h2><font color="#009999">Chapter 22 - Templates</font></h2>
<font size="+1">

<ul>
	<li>Provides another level of abstraction</li>
	<li>A template class or function can work with many different <i>types</i>
		</li>
	<li>Handled at compile time (efficient)</li>
</ul>

</font>

<hr><h2><font color="#009999">22.1 Template Functions</font></h2>
<font size="+1">

<ul>
	<li>E.g., a function to print an array of <tt>int</tt>:
		<blockquote>
<pre>void print(ostream&amp; out, int data[], int count)
{
   out &lt;&lt; "[";
   for (int i = 0; i &lt; count; i++)
   {
      if (i &gt; 0)
         out &lt;&lt; ",";
      out &lt;&lt; data[i];
   }
   out &lt;&lt; "]";
}</pre>
		</blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">22.1 Template Functions</font></h2>
<font size="+1">

<ul>
	<li>Your next project requires the same for an array of doubles:
		<ul>
			<li>Cut and paste?</li>
			<li>Search and replace?</li>
		</ul>
	</li>
	<li>Template function is a better solution</li>
</ul>

</font>

<hr><h2><font color="#009999">22.1 Template Functions (cont.)</font></h2>
<font size="+1">

<ul>
	<li>Function parameterized by type</li>
	<li>Abstract away the differences (argument types)</li>
	<li>Use the template prefix, <tt>template</tt> followed by a list of
	<i>type parameters</i>:</li>
</ul>

</font>

<hr><h2><font color="#009999">22.1 Template Functions (cont.)</font></h2>
<font size="+1">

<blockquote>
<pre><font color="#009999">template&lt;typename T&gt;</font>
void print(ostream&amp; out, <font color="#009999">T</font> data[], int count)
{
   out &lt;&lt; "[";
   for (int i = 0; i &lt; count; i++)
   {
      if (i &gt; 0)
         out &lt;&lt; ",";
      out &lt;&lt; data[i];
   }
   out &lt;&lt; "]";
}</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">22.1 Template Functions (cont.)</font></h2>
<font size="+1">

<table width='100%' border="1" cellpadding="4" bgcolor="#00cccc">
	<tr>
		<td bgcolor="#ffffff"><font size="+1"><font color="#009999">Syntax 22.1:
			Template Function Definition</font>

<pre>template&lt;typename <i>type_var</i><sub>1</sub>, ..., typename <i>type_var<sub>n</sub></i>&gt;
<i>return_type function_name</i>(<i>parameters</i>)
{
   <i>statements</i>
}</pre>

			<table border="0" cellpadding="4">
				<tr>
					<td valign="top"><font size="+1" color="#009999">Purpose:</font></td>
					<td><font size="+1">Define a function that can be reused for different
						types of arguments</font></td>
				</tr>
			</table>
		</td>
	</tr>
</table>

</font>

<hr><h2><font color="#009999">22.1 Template Functions (cont.)</font></h2>
<font size="+1">

<table width='100%' border="1" cellpadding="4" bgcolor="#00cccc">
	<tr>
		<td bgcolor="#ffffff"><font size="+1"><font color="#009999">Syntax 22.1:
			Template Function Definition (cont.)</font>

			<table border="0" cellpadding="4">
				<tr>
					<td valign="top"><font size="+1" color="#009999">
						Example:</font></td>
					<td><font size="+1">

<pre>
template&lt;typename T&gt;
void print(ostream&amp; out, T data[], int count)
{
   out &lt;&lt; "[";
   for (int i = 0; i &lt; count; i++)
   {
      out &lt;&lt; data[i];
      if (i + 1 &lt; count)
         out &lt;&lt; ",";
   }
   out &lt;&lt; "]";
}
</pre>
						</font>
					</td>
				</tr>
			</table>
			</font>
		</td>
	</tr>
</table>

</font>

<hr><h2><font color="#009999">22.1 Template Functions (cont.)</font></h2>
<font size="+1">

<ul>
	<li><tt>T</tt> is arbitrary; any legal C identifier</li>
	<li><tt>typename</tt> (or <tt>class</tt>) indicates that the value of
		<tt>T</tt> will be a type</li>
	<li><tt>T</tt> could represent any type</li>
	<li>Its type is inferred from the arguments of the call:
		<blockquote>
<pre>int a[] = {2, 4, 5};
print(cout, a, 3); <font color="#0000cc">// Will use int print</font>
double b[] = {3.14159, 2.7};
print(cout, b, 2); <font color="#0000cc">// Will use double print</font>
string c[] = {"Fred", "Sally", "Alice"};
print(cout, c, 3); <font color="#0000cc">// Will use string print</font></pre>
		</blockquote>
	<li>Within the function body <tt>T</tt> can be used wherever that type
		would be appropriate</li>
</ul>

</font>

<hr><h2><font color="#009999">Common Error 22.1</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">

<p>A type argument is characterized implicitly, by its use in the function.

<ul>
	<li>The typical <tt>max</tt> function:
		<blockquote>
<pre>
template&lt;typename T&gt;
T max(const T&amp; left, const T&amp; right)
{
   if (left &lt; right)
      return right;
   return left;
}</pre>
		</blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">Common Error 22.1 (cont.)</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">

<ul>
	<li>The <tt>&lt;</tt> operator must be defined for <tt>T</tt></li>
	<li>This won't work:
		<blockquote><tt>
			Employee mary("Mary Smith", 25000);
			<br>Employee fred("Fred Jones", 37500);
			<br>Employee big = max(mary, fred);
				<font color="#0000cc">// Error - invalid types</font>
		</tt></blockquote>
	</li>
	<li>Compiler must see the entire definition of a function template</li>
</ul>

</font>

<hr><h2><font color="#009999">Common Error 22.1 (cont.)</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">

<p>Coercion doesn't happen.  You can't mix types.

<ul>
	<li>Consider:
		<blockquote><tt>
			double e = max( 2, 3.13 );	<font color="#0000cc">
			// Error - cannot infer type argument</font>
		</tt></blockquote>
	</li>
	<li>Type argument(s) may be supplied explicitly:
		<blockquote><tt>
			double e = max&lt;double&gt;( 2, 3.13 );	<font color="#0000cc">
			// OK - integer will be converted to a double</font>
		</tt></blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">22.2 Compile-Time Polymorphism</font></h2>
<font size="+1">

<ul>
	<li>Templates instantiated in many different ways</li>
	<li>Does its work at compile time
		<ul>
			<li>Compiler creates <i>template functions</i> from
				the <i>function template</i>, as needed</li>
			<li>Few run-time costs</li>
			<li>A function template prototype is meaningless</li>
		</ul>
	</li>
	<li>Templates are commonly stored in included files</li>
	<li>Not compiled separately (sect. 22.6)</li>
	<li>Compiler looks for <nobr>non-templates</nobr> first</li>
</ul>

</font>

<hr><h2><font color="#009999">22.3 Template Classes</font></h2>
<font size="+1">

<ul>
	<li>The most common examples are container classes</li>
	<li>Consider a function that finds the max and min values of a vector</li>
	<li>make a <tt>Pair</tt> class to return both values
		<blockquote>
<pre>Pair minmax(vector&lt;int&gt; v)
{
   int min = v[0];
   int max = v[0];
   for (int i = 1; i &lt; v.size(); i++)
   {
      if (v[i] &lt; min) min = v[i];
      if (v[i] &gt; max) max = v[i];
   }
   return Pair(min, max);
}</pre>
		</blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">22.3 Template Classes (cont.)</font></h2>
<font size="+1">

<ul>
	<li>To use:
		<blockquote><tt>
			Pair p = minmax(data);
			<br>cout <nobr>&lt;&lt;</nobr> <nobr>p.get_first()</nobr> <nobr>&lt;&lt;</nobr> "&nbsp;" <nobr>&lt;&lt;</nobr> <nobr>p.get_second()</nobr> <nobr>&lt;&lt;</nobr> <nobr>"\n";</nobr>
		</tt></blockquote>
	</li>
</ul>

<p>Example:  non-template class:

<blockquote>
<pre>class Pair
{
   public:
      Pair(int a, int b);
      int get_first() const;
      int get_second() const;
   private:
      int first;
      int second;
};</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">22.3 Template Classes (cont.)</font></h2>
<font size="+1">

<blockquote>
<pre>inline Pair::Pair(int a, int b)
{
   first = a;
   second = b;
}

inline int Pair::get_first() const
{
   return first;
}

inline int Pair::get_second() const
{
   return second;
}</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">22.3 Template Classes (cont.)</font></h2>
<font size="+1">

<ul>
	<li><tt>Pair</tt> is not very flexible</li>
		<ul>
			<li>We'd like a generic pair</li>
			<li>One that can hold disparate types</li>
		</ul>
	</li>
	<li>Type arguments can not be inferred</li>
	<li>They are explicitly named at declaration:
		<blockquote><tt>
			Pair&lt;int, int&gt;
			<br>Pair&lt;string, int&gt;
		</tt></blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">22.3 Template Classes (cont.)</font></h2>
<font size="+1">

<ul>
	<li>Replace types with <tt>F</tt> and <tt>S</tt>
		<blockquote>
<pre>template&lt;typename F, typename S&gt;
class Pair
{
public:
   Pair(const F&amp; a, const S&amp; b);
   F get_first() const;
   S get_second() const;
private:
   F first;
   S second;
};</pre>
		</blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">22.3 Template Classes (cont.)</font></h2>
<font size="+1">

<ul>
	<li>Turn <i>each</i> member function into a template:</li>
</ul>

<blockquote>
<pre>template&lt;typename F, typename S&gt;
inline Pair&lt;F, S&gt;::Pair(const F&amp; a, const S&amp; b)
{
   first = a;
   second = b;
}</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">22.3 Template Classes (cont.)</font></h2>
<font size="+1">

<blockquote>
<pre>template&lt;typename F, typename S&gt;
inline F Pair&lt;F, S&gt;::get_first() const
{
   return first;
}

template&lt;typename F, typename S&gt;
inline S Pair&lt;F, S&gt;::get_second() const
{
   return second;
}</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">22.3 Template Classes (cont.)</font></h2>
<font size="+1">

<ul>
	<li><tt>Pair</tt> is a template, not a class</li>
	<li><tt>Pair&lt;F,S&gt;</tt> precedes each declaration</li>
	<li>Compare to the STL <tt>pair</tt> class</li>
	<li>These are templates, not functions</li>
	<li>Must be included in each compilation module</li>
</ul>

</font>

<hr><h2><font color="#009999">22.3 Template Classes (cont.)</font></h2>
<font size="+1">

<table width='90%' border="1" cellpadding="4" bgcolor="#00cccc">
	<tr>
		<td bgcolor="#ffffff"><font size="+1"><font color="#009999">Syntax 22.2
			Template Class Definition</font>

<pre>template&lt;typename <i>type_var</i><sub>1</sub>, ..., typename <i>type_var<sub>n</sub></i>&gt;
class <i>ClassName</i>
{
   <i>features</i>
};</pre>

			<table border="0" cellpadding="4">
				<tr>
					<td valign="top"><font size="+1" color="#009999">Purpose:</font></td>
					<td><font size="+1">Define a class template with a type parameter.
						</font></td>
				</tr>
			</table>
		</td>
	</tr>
</table>

</font>

<hr><h2><font color="#009999">22.3 Template Classes (cont.)</font></h2>
<font size="+1">

<table width='90%' border="1" cellpadding="4" bgcolor="#00cccc">
	<tr>
		<td bgcolor="#ffffff"><font size="+1"><font color="#009999">Syntax 22.2
			Template Class Definition (cont.)</font>

			<table border="0" cellpadding="4">
				<tr>
					<td valign="top"><font size="+1" color="#009999">
						Example:</font></td>
					<td><font size="+1">

<pre>template&lt;typename F, typename S&gt;
class Pair
{
public:
   Pair(const F&amp; a, const S&amp; b);
   F get_first() const;
   S get_second() const;
private:
   F first;
   S second;
};</pre>
						</font>
					</td>
				</tr>
			</table>
			</font>
		</td>
	</tr>
</table>

</font>

<hr><h2><font color="#009999">22.3 Template Classes (cont.)</font></h2>
<font size="+1">

<table border="1" cellpadding="4" bgcolor="#00cccc">
	<tr>
		<td bgcolor="#ffffff"><font size="+1"><font color="#009999">Syntax 22.3:
			Template Member Function Definition</font>

<pre>template&lt;typename <i>type_variable</i>&gt;
{
   <i>statements</i>
}</pre>

			<table border="0" cellpadding="4">
				<tr>
					<td valign="top"><font size="+1" color="#009999">
						Example:</font></td>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -