I l@ve RuBoard Previous Section Next Section

6.8 Member Template Functions

It is also possible to define a member template function. Let's look at an example and then walk through it:



class PrintIt { 


public: 


    PrintIt( ostream &os ) 


           : _os( os ){} 





    // a member template function 


    template <typename elemType> 


    void print( const elemType &elem, char delimiter = '\n' ) 


              { _os << elem << delimiter; } 


private: 


    ostream& _os; 


}; 

PrintIt is a nontemplate class that is initialized to an output stream. It provides a member template print() function that writes an object of an arbitrary type to that output stream. By making print() a member template function, we can provide a single instance that supports any type for which an instance of the output operator can be applied. Were we to parameterize PrintIt by the type of element we wish to output, we would create a new class template for each distinct type. Under this implementation, there is only a single PrintIt class. Here is how we might use it:



int main() 


{ 


    PrintIt to_standard_out( cout ); 


    to_standard_out.print( "hello" ); 


    to_standard_out.print( 1024 ); 





    string my_string( "i am a string" ); 


    to_standard_out.print( my_string ); 


} 

When compiled and executed, this generates the following output:



hello 


1024 


i am a string 

A template class can also define a member template function. For example, we might parameterize PrintIt by its ostream type while maintaining print() as a member template function:



template <typename OutStream> 


class PrintIt { 


public: 


    PrintIt( OutStream &os ) 


           : _os( os ){} 





    template <typename elemType> 


    void print( const elemType &elem, char delimiter = '\n' ) 


              { _os << elem << delimiter; } 


private: 


    ostream& _os; 


}; 

Here is our modified program:



int main() 


{ 


    PrintIt<ostream> to_standard_out( cout ); 


    to_standard_out.print( "hello" ); 


    to_standard_out.print( 1024 ); 





    string my_string( "i am a string" ); 


    to_standard_out.print( my_string ); 


} 

There is a great deal more to be said about templates than I have covered here. For a more detailed look at the C++ template facility, see [LIPPMAN98], Chapter 10 (Function Templates) and Chapter 16 (Class Templates) and [STROUSTRUP97], Chapter 13.

Exercise 6.1

Rewrite the following class definition to make it a class template:



class example { 


public: 


      example( double min, double max ); 


      example( const double *array, int size ); 


      double& operator[]( int index ); 


      bool operator==( const example1& ) const; 


      bool insert( const double*, int ); 


      bool insert( double ); 


      double min() const { return _min; } 


      double max() const { return _max; } 


      void min( double ); 


      void max( double ); 


      int count( double value ) const; 


private: 


      int size; 


      double *parray; 


      double _min; 


      double _max; 


}; 

Exercise 6.2

Reimplement the Matrix class of Exercise 4.3 as a template. In addition, extend it to support arbitrary row and column size using heap memory. Allocate the memory in the constructor and deallocate it in the destructor.

    I l@ve RuBoard Previous Section Next Section