Advanced Templates
Templates with Multiple Type Parameters
A class template may have more than one type parameter.
The template below defines a class that encapsulates pairs
of objects -- the first is the key, the second is the data.
#include
#include
using namespace std;
// defines Pair as a template with two
// template parameters
template < class Key, class Data >
class Pair
{
public:
// default constructor
Pair( );
// destructor
~Pair( );
// copy constructor
Pair( const Pair& pair);
// equality operator
bool operator== (const Pair& rhs) const;
private:
Key m_key;
Data m_data;
};
// Pair's equality operator
template
bool Pair::operator== (const Pair& rhs) const
{
return m_key == rhs.m_key && m_data == rhs.m_data;
}
int main ( )
{
string bob = "bob";
string mary = "mary";
// use pair to associate a string and its length
Pair< int, string > boy (bob.length(), bob);
Pair< int, string > girl (mary.length(), mary);
// make a new pair using copy constructor
Pair dad = boy;
// check for equality
if (bob == girl)
cout << "They match\n";
// use Pair for names and Employee object
Employee john, mark;
Pair< string, Employee> boss ("john", john);
Pair< string, Employee> worker( "mark", mark);
if (boss == worker)
cout << "A real small company\n";
return 0;
}
Templates can have Nontype Parameters
Not all of the parameters for a template need be class type
parameters. For instance, we could have written the SmartArray
template to include the size as a nontype template parameter
as shown below. This technique avoids the necessity of using
dynamically allocated memory for the SmartArray class.
template
class SmartArray
{
public:
SmartArray ( );
// other members
private:
int m_size;
T m_data[ size ];
};
template< class T, int size>
SmartArray::SmartArray( )
{
m_size = size;
}
Templates as Parameters
When we wish to pass a template class to a function, that function becomes
a function template. Here's the definition for a function that sorts
the elements of a smart arrary. We want to use it for all types of
smart arrays, so we pass the smart array template as the parameter.
template
void Sort ( SmartArray& theArray)
{
// code here
}
Templates and Friends
We can make functions friends of templates too. For example, if we want to output
SmartArrays using operator<<, we define the function as a template
as above
template
ostream& operator<< (ostream& out, const SmartArray& theArray)
{
// code here
}
In the SmartArray class definition we declare operator<< to be our friend in the usual way, but we must tell the compiler that operator<<
is a template function. One easy way to do this by including "<>" after the
name of the function.
template
class SmartArray
{
friend ostream& operator<< <> (ostream& out, const SmartArray& theArray);
// the rest of the SmartArray class definition
};
There is one other key component to completing your implementation of a
templated friend in your application, in order to allow the compiler to
understand where the operator belongs and which class it belongs to. We use a
technique called "forward declaring" in order to notify the compiler of each
of these components. Essentially "forward declaring" is prototyping everything
that you will be declaring:
template class FooClass; // forward-declaring class
template ostream& operator<< (ostream& out, const FooClass &foo); // forward-declaring insertion stream
template
class FooClass
{
public:
friend ostream& operator<< <> (ostream& out, const FooClass &foo);
private:
};
template
ostream& operator<< (ostream& out, const FooClass &foo)
{
// implementation
}
Last Modified: Monday, 28-Aug-2006 10:16:05 EDT