📄 index.html
字号:
<!-- -*-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& out, int data[], int count)
{
out << "[";
for (int i = 0; i < count; i++)
{
if (i > 0)
out << ",";
out << data[i];
}
out << "]";
}</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<typename T></font>
void print(ostream& out, <font color="#009999">T</font> data[], int count)
{
out << "[";
for (int i = 0; i < count; i++)
{
if (i > 0)
out << ",";
out << data[i];
}
out << "]";
}</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<typename <i>type_var</i><sub>1</sub>, ..., typename <i>type_var<sub>n</sub></i>>
<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<typename T>
void print(ostream& out, T data[], int count)
{
out << "[";
for (int i = 0; i < count; i++)
{
out << data[i];
if (i + 1 < count)
out << ",";
}
out << "]";
}
</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<typename T>
T max(const T& left, const T& right)
{
if (left < 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><</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<double>( 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<int> v)
{
int min = v[0];
int max = v[0];
for (int i = 1; i < v.size(); i++)
{
if (v[i] < min) min = v[i];
if (v[i] > 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><<</nobr> <nobr>p.get_first()</nobr> <nobr><<</nobr> " " <nobr><<</nobr> <nobr>p.get_second()</nobr> <nobr><<</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<int, int>
<br>Pair<string, int>
</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<typename F, typename S>
class Pair
{
public:
Pair(const F& a, const S& 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<typename F, typename S>
inline Pair<F, S>::Pair(const F& a, const S& 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<typename F, typename S>
inline F Pair<F, S>::get_first() const
{
return first;
}
template<typename F, typename S>
inline S Pair<F, S>::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<F,S></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<typename <i>type_var</i><sub>1</sub>, ..., typename <i>type_var<sub>n</sub></i>>
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<typename F, typename S>
class Pair
{
public:
Pair(const F& a, const S& 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<typename <i>type_variable</i>>
{
<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 + -