                                 10.  

474

   template <class Type>
   Type min2( Type a, Type b ) {
      return a < b ? a : b;
   }

   int main() {
      // : min( int, int );
      min( 10, 20 );
      // : min( double, double );
      min( 10.0, 20.0 );
      return 0;
   }

       -,   ,  -, 
   .
   -    .    ,  
         .

   template <class Type, int size>
      Type min( Type (&arr) [size] );

              
,        ,    
:

   template <class Type, int size>
   Type min( const Type (&r_array)[size] )
   {
      /*    
       *     */
      Type min_val = r_array[0];
      for ( int i = 1; i < size; ++i )
         if ( r_array[i] < min_val )
           min_val = r_array[i];

      return min_val;
   }

           
. (       .)
        7.3,    ,   
  ,     - 
  .    ,   
 min()    ,      .  
  ,            int,
    ( )  
 min().
         ,      
,    ,     . 
    tmp  double,  ,    
Type:


   typedef double Type;
   template <class Type>
   Type min( Type a, Type b )
   {
      // tmp    ,    Type,   
      //  typedef
      Type tm = a < b ? a : b;
      return tmp;
   }

  ,     ,    
 ,   -  :

   -       
:

             .
,       :

480


   // :      Type
   template <class Type, class Type>
      Type min( Type, Type );


              
 :

   // :    Type  
   template <class Type>

   Type min( Type, Type );
   Type max( Type, Type );

           . ,  
 min()        :

   //    min()        

   //   
   template <class T> T min( T, T );
   template <class U> U min( U, U );

   //   
   template <class Type>

   Type min( Type a, Type b ) { /* ... */ }

        -  , 
  ;     . ,  
     Parm::name   Parm   -
,  ,    ,  name  -
 Parm?

   template <class Parm, class U>
   Parm minus( Parm* array, U value )
   {
      Parm::name * p; //     ?
                      //    

     ,   name ,   ,
  Parm,     .
      ,  
 ,    .    
 typename. ,   ,   Parm::name  
 minus()    , ,    
 ,      :

   template <class Parm, class U>
   Parm minus( Parm* array, U value )
   {
      typename Parm::name * p; //    
   }

     typename       
 ,    .

        inline  extern     .
    ,     template.

   // :    
   template <typename Type>
   inline
   Type min( Type, Type );


                            10.2.   

   //    min()
   //  - Type  - size
   template <typename Type, int size>
      Type min( Type (&r_array)[size] )
   {
      Type min_val = r_array[0];
      for ( int i = 1; i < size; ++i )
        if ( r_array[i] < min_val )
          min_val = r_array[i];
        return min_val;
   }

   // size   -- ok
   // size =     
   int ia[] = { 10, 7, 14, 3, 25 };
   double da[6] = { 10.2, 7.1, 14.5, 3.2, 25.0, 16.8 };

   #include <iostream>
   int main()
   {
      //  min()    5   int
      //  Type => int, size => 5
      int i = min( ia );

      if ( i != 3 )
         cout << "??oops: integer min() failed\n";
      else cout << "!!ok: integer min() worked\n";

      //  min()    6   double
      //  Type => double, size => 6
      double d = min( da );
      if ( d != 3.2 )
         cout << "??oops: double min() failed\n";
      else cout << "!!ok: double min() worked\n";

      return 0;
   }

              
    (deduction)  . (
      .    10.4   
   .)
       ,     . 
   pf   
 .       
,    pf:

   template <typename Type, int size>
   Type min( Type (&p_array)[size] ) { /* ... */ }

   // pf   int min( int (&)[10] )
   int (*pf)(int (&)[10]) = &min;

       ,    ,   
      .    
,     :

   template <typename Type, int size>
      Type min( Type (&r_array)[size] ) { /* ... */ }

   typedef int (&rai)[10];
   typedef double (&rad)[20];

   void func( int (*)(rai) );
   void func( double (*)(rad) );

   int main() {
      // :   min()?
      func( &min );

   }

    func()          
  Type,     size. 
  func()      :

   min( double (*)(double(&)[20]) )
   min( int (*)(int(&)[10]) )

        func() ,  
        .
     ,        
:

   int main() {
      // :       
      func( static_cast< double(*)(rad) >(&min) );
   }

   , ,     ,    
 10.4.

484

                        10.3.    

           
  l-,   .   ,
  pval   int*,    l-   int.

   void f( int pval[9] ) {
      // : Type (&)[] != int*
      int jval = min( pval );
   }

        ,    
        .
    :  l-, 
     ,   
.     .

488

    ,       
 :

  1.       ,  ,
           - 
     .
  2.    ,      
        .
  3.         
      .       
     :

       l-
       
            ,  
           T<args>&  T<args>*,   
       args      .

  4.            
     ,   ,     
      ,      .


                        10.4.     A

           .

   ,      unsigned int    
 T      min5(),   
   :

   //  min5( unsigned int, unsigned int )
   min5< unsigned int >( ui, 1024 );

    ,     min5()    1024, ..
  int.          
    unsigned int,    
    unsigned int    
 .

      ,        
  :

   // T1       
   template <class T1, class T2, class T3>
   T1 sum( T2, T3 );

            ,
T1      .   , 
  T1        .

            ,  
   .

    ,       , 
  ; ,    . 
        
       C++.

   ,         ,
        
    ,    . -
,        
.  -,      ,  
       , 
      .  
,     ,  ,   -
     .   
    .


                     10.5.    

                     10.5.1.    

            ,  
 .      ,

                    10.5.2.    

            ,
        ,

         ,  ,  , 
    :       
,       C++.

                    10.5.3.   

            
  ,     .  ,
,  ,      ,   
 ,        
   .     (
)        
.             
       , 
 .

         ,    :
      .     
  ,      .

    ,    ,  
.    C++     ,
   ,   .

   template <typename Type>
      Type sum( Type op1, Type op2 ) { /* ... */ }

   //   
   template int* sum< int* >( int*, int );

           ,
    .    
 . ,  VisualAge for C++  Windows  3.5 
IBM    /ft-.      , 
 ,     ,   
 .
   ,          
 ,    /ft-,      - ,
    .

                  10.6.    

   //   
   template <class T>
      T max( T t1, T t2 ) {
         return ( t1 > t2 ? t1 : t2 );
      }

         ,    
 template     <>,    
 .

   #include <cstring>

   //    const char*:
   //     
   //   

   typedef const char *PCC;
   template<> PCC max< PCC >( PCC s1, PCC s2 ) {
      return ( strcmp( s1, s2 ) > 0 ? s1 : s2 );
   }

       max()     const char* 
 .      
    ,   .

   int main() {
      //   : int max< int >( int, int );
      int i = max( 10, 5 );

     //   :
     // const char* max< const char* >( const char*, const char* );
     const char *p = max( "hello", "world" );
      
     cout << "i: " << i << " p: " << p << endl;
     return 0;
   }

   template <class T1, class T2, class T3>
      T1 sum( T2 op1, T3 op2 );

   //   
 
   // :    T1    ;
   //     
   template<> double sum( float, float );

   // :   T1  ,
   // T2  T3     float
   template<> double sum<double>( float, float );

   // :    
   template<> int sum<int,char>( char, char );


                        10.7.    

                   10.8.     A

       ,      . 
,           
:

       sum(),       
 ,          ,    
  .

       ,   ,
         , 
,     :

                  10.9.      

           
  ,       .

     ,    ,  
.     ,   ,  
   ,    .   
         , 
  .

                     10.10.      

524

                             10.11.   

     6  ,     C++   
vector,        Array.   12
  ,   ,
   6.    , sort(),   
 .        
sort()    Array,    
  C++.

   template <class elemType>
      void sort( Array<elemType> &array, int low, int high ) 
      {

      if ( low < high ) {
         int lo = low;
         int hi = high + 1;
         elemType elem = array[lo];
           
         for (;;) {
            while ( min( array[++lo], elem ) != elem && lo < high ) ;
            while ( min( array[--hi], elem ) == elem && hi > low ) ;
             
            if (lo < hi)
               swap( array, lo, hi );
            else break;
         }
          
         swap( array, low, hi );
         sort( array, low, hi-1 );
         sort( array, hi+1, high );
      }
   }


  ,      
 ,       sort().
min()          
 :

   template <class Type>
      Type min( Type a, Type b ) {
         return a < b ? a : b;
      }

526

swap()          :

   template <class elemType>
      void swap( Array<elemType> &array, int i, int j )
   {
      elemType tmp = array[ i ];
      array[ i ] = array[ j ];
      array[ j ] = tmp;
   }

  ,   sort()  ,   
    .   display()
   ,     Array, 
    :

   #include <iostream>
   template <class elemType>
      void display( Array<elemType> &array )
   { // : < 0 1 2 3 4 5 >
      cout << "< ";
      for ( int ix = 0; ix < array.size(); ++ix )
         cout << array[ix] << " ";
      cout << ">\n";
   }

   #include <iostream>
   #include <string>
   #include "Array.h"

   double da[10] = { 26.7, 5.7, 37.7, 1.7, 61.7, 11.7, 59.7,
                     15.7, 48.7, 19.7 };
   int ia[16] = { 503, 87, 512, 61, 908, 170, 897, 275, 653,
                  426, 154, 509, 612, 677, 765, 703 };
   string sa[11] = { "a", "heavy", "snow", "was", "falling", "when",
                     "they", "left", "the", "police", "station" };

   int main() {
      //     arrd
      Array<double> arrd( da, sizeof(da)/sizeof(da[0]) );

      //     arri
      Array<int> arri( ia, sizeof(ia)/sizeof(ia[0]) );

      //     arrs
      Array<string> arrs( sa, sizeof(sa)/sizeof(sa[0]) );
 
      cout << "sort array of doubles (size == "
           << arrd.size() << ")" << endl;
      sort(arrd, 0, arrd.size()-1 );
      display(arrd);

      cout << "sort array of ints (size == "
           << arri.size() << ")" << endl;
      sort(arri, 0, arri.size()-1 );
      display(arri);
 
      cout << "sort array of strings (size == "
           << arrs.size() << ")" << endl;
      sort(arrs, 0, arrs.size()-1 );
      display(arrs);

      return 0;
   }

