                                                          ++   475

10

10.  

      ,    ,    
   .   ,     ,
      ,   ,    .
    ,    ++,   
      ,   .   
            C++. 
       ,        ,  
       .    
   ,   .     
    ,      (deduction) 
     ,       (instantiation)
    .    ,   
            
     ,   ,   
     .       ,
        .  ,
             
   .         
     ,       . 
     .

10.1.   

     ,       
   . ,    
min() ,   ,    
   ,    :

int min( int a, int b ) {
return a < b ? a : b;
}
double min( double a, double b ) {
return a < b ? a : b;
}

          min()
  ,  :

   #define min(a, b) ((a) < (b) ? (a) : (b))

          .   
      min(), :

++   476

   min( 10, 20 );
   min( 10.0, 20.0 );

       :     
  ,      .  
    :     a  b, 
      :

#include <iostream>

#define min(a,b) ((a) < (b) ? (a) : (b))

const int size = 10;
int ia[size];

int main() {
int elem_cnt = 0;
int *p = &ia[0];

//    
while ( min(p++,&ia[size]) != &ia[size] )
++elem_cnt;

cout << "elem_cnt : " << elem_cnt
<< "\texpecting: " << size << endl;

return 0;
}

     ,        ia
 .      min()  ,  
   -    . 
   ,   
:

   elem_cnt : 5 expecting: 10

         ,   
       ( 
         ),
       C++,     .
     ,     
   .      
    (..     
),    .      ,
        ,
  , , ,   min().
       min():

++   477

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;
}

       min()     
 ,    :

   elem_cnt : 10 expecting: 10

   (   C++       
,   min().      12.   
         
 .)
    ,         
  template,      
,     '<'  '>',    ,
 .     -, 
 ,  -,   
.
   -     class    typename, 
  .    ,   
      .  
  .       Type, 
    :

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

     (  )   -
       .
   int, double, char*, vector<int>  list<double> 
  .
   -    .    ,  
         .
, size   -,     arr:

++   478

   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;
}

      Type   ,   min(), 
 r_array     min_val; size   
r_array.        min()  Type
        , 
 size      . (,   
  :      ).
           
. (       .)
       min()    . 
    7.3,    ,   
  ,     - 
  .    ,   
 min()    ,      .  
  ,            int,
    ( )  
 min().
           .
-   ;      , 
     ,   
     . -  
   ,    ,  
          
.

++   479

// size   -  
//   const int
template <class Type, int size>
Type min( const Type (&r_array)[size] )
{
const int loc_size = size;
Type loc_array[loc_size];
// ...
}

        ,      
,    ,     . 
    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;
}

     ,     ,    
 ,   -  :

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

    -       
:

// : T1   ,  min(),
//  T2  T3  -  
template <class T1, class T2, class T3>
T1 min( T2, T3 );

             .
,       :

++   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 ) { /* ... */ }

             
  .    Type   
  :

#include <vector>
// : Type      
template <class Type>
Type sum( const vector<Type> &, Type );

        -,     
   class  typename:

// :   typename  class  
template <typename T, class U>
T minus( T*, U );
// :   <typename T, class U> 
// <typename T, typename U>
template <typename T, U>
T sum( T*, U );

++   481

          typename  class 
  , , .    
    -      
 (       minus()). 
 -  ,   ,  
 typename,   class,    ,      .
        ,    C++,
         class. (   
,  class ,  typename,      .)
     typename    . (  
  ,   .     
     Design and Evolution of C++.)
         -  , 
  ;     . ,  
     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.

++   482

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

 10.1

,       . 
.

(a) template <class T, U, class V>
void foo( T, U, V );

(b) template <class T>
T foo( int *T );

(c) template <class T1, typename T2, class T3>
T1 foo( T2, T3 );

(d) inline template <typename T>
T foo( T, unsigned int* );

(e) template <class myT, class myT>
void foo( myT, myT );

(f) template <class T>
foo( T, T );

(g) typedef char Ctype;
template <class Ctype>
Ctype foo( Ctype a, Ctype b );

 10.2

        ? ?

(a) template <class Type>
Type bar( Type, Type );
template <class Type>
Type bar( Type, Type );

(b) template <class T1, class T2>
void bar( T1, T2 );
template <typename C1, typename C2>
void bar( C1, C2 );

 10.3

++   483

     putValues()   7.3.3   .  
,      (      
)    ,    . 
  .

10.2.   

     ,     ,  
    .   
 .   ,     
   . ,    min()
 :         int,   
      double:

//    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;
}

   

   int i = min( ia );

++   484

      min(),   Type
  int,  size  5:

int min( int (&r_array)[5] )
{
int min_val = r_array[0];
for ( int i = 1; i < 5; ++i )
if ( r_array[i] < min_val )
min_val = r_array[i];

return min_val;
}

    

   double d = min( da );

  min(),   Type   double,  size  6:
          - 
-.       , 
   ,   ,   
.         
  ia (   int)  da (   double). 
        
    (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;

    pf         int(&)[10],  
   Type     size  
min().   Type    int,    
size  10.     min(int(&)[10]), 
 pf   .
       ,    ,   
      .    
,     :

++   485

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( int (*)(int(&)[10]) )
min( double (*)(double(&)[20]) )

        func() ,  
        .
     ,        
:

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

   , ,     ,    
 10.4.

10.3.    

             
    .    
 .
       min()       Type:

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

++   486

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

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

            ,
   . ,   min()
 :

double da[8] = { 10.3, 7.2, 14.0, 3.8, 25.7, 6.4, 5.5, 16.8 };
int i1 = min( da );

   min()       
 double     double.   i1 
    int.   ,    min()
     int,     
.
        ,    
        .
    :  l-, 
     ,   
.     .
   ,   l-     l-  r-
,     ,    
 (     9.3).    
       min2() c 
  Type    .   min2() 
    Type*. size     ,  
 min(),      ,    
    :

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

return min_val;
}

++   487

min2()  ,         int, 
  :

int ai[4] = { 12, 8, 73, 45 };
int main() {
int size = sizeof (ai) / sizeof (ai[0]);
// :    
min2( ai, size );
}

      ai      int    
    Type*. , 
    ,   ai    int*
     Type,      int,  
  min2(int*, int).
      const  volatile   (
     9.3).   
       min3() 
    const Type*:

template <class Type>
//     const Type*
Type min3( const Type* array, int size ) {
// ...
}

min3()  ,  int*     ,  
 :

int *pi = &ai;
// :     const int*
int i = min3( pi, 4 );

   pi     int     
  const Type*. ,  
 ,      const int*   
  Type,      int,  
  min3(const int*, int).
         ,   
.     ,    
   ,      ,
  .    ,
    min4()    Array<Type>&, 
Array    ,    2.5. (  16  
   .)

++   488

template <class Type>
class Array { /* ... */ }

template <class Type>
Type min4( Array<Type>& array )
{
Type min_val = array[0];
for ( int i = 1; i < array.size(); ++i )
if ( array[i] < min_val )
min_val = array[i];

return min_val;
}

min4()  ,      ArrayRC<int>, 
   . (ArrayRC    ,   
 2;       17  18.)

template <class Type>
class ArrayRC : public Array<Type> { /* ... */ };
int main() {
ArrayRC<int> ia_rc(10);
min4( ia_rc );
}

     ia_rc   ArrayRC<int>.     
  Array<Type>&.       ArrayRC<int>
 Array<int>,       ,  
   .    
 ,        .
 ,     ArrayRC<int>   
Array<int>,      Type   int 
  min4(Array<int>&).
            
 .        
  ,        ,
        :

template <class T> T min5( T, T ) { /* ... */ }
unsigned int ui;
int main() {
// :   min5( unsigned int, int )
//  : min5( unsigned int, unsigned int ) 
// min5( int, int )
min5( ui, 1024 );
}

             :  int, 
unsigned int,         T. 

++   489

 T,     ,   int.   
T,     ,   unsigned int.  
 ,        
   . (  ,    
    min5().   10.4  ,   .)
            
 ,       . 
     .   
 sum()    .   op1  
     Type ,    
op2  .

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

        sum()    
. ( ,    
,    9.3.) :

int ai[] = { ... };
double dd;
int main() {
//  sum( int, int )
sum( ai[0], dd );
}

        dd    
 int.        sum(), 
         .  
   sum(int,int).  dd    int 
        .
    ,       
 :

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

       l-
       

++   490

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

  4.            
     ,   ,     
      ,      .

 10.4

      ,     
 ,      .

 10.5

       :

template <class Type>
Type min3( const Type* array, int size ) { /* ... */ }
template <class Type>
Type min5( Type p1, Type p2 ) { /* ... */ }

        ? ?

double dobj1, dobj2;
float fobj1, fobj2;
char cobj1, cobj2;
int ai[5] = { 511, 16, 8, 63, 34 };

(a) min5( cobj2, 'c' );
(b) min5( dobj1, fobj1 );
(c) min3( ai, cobj1 );

10.4.     A

           .
       min5(),     
        ,    
    .
             ,
          
,       .
,      unsigned int    
 T      min5(),   
   :

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

++   491

         <unsigned int>    .
    ,      
.
    ,     min5()    1024, ..
  int.          
    unsigned int,    
    unsigned int    
 .
       ,       
      
  .  int  unsigned int   
 .      ,     ,
   . ,    
         
     .
         , 
       ,  
.   .     
  sum() ,      , 
        ,  
 .   ?      ?

//      : T  U
template <class T, class U>
??? sum( T, U );

         ,    ,  
  :

char ch; unsigned int ui;
//  T,  U       
sum( ch, ui ); // : U sum( T, U );
sum( ui, ch ); // : T sum( T, U );

      ,        
  :

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

            ,
T1      .   , 
  T1        . , 

++   492

  sum()     ,   
    T1. :

typedef unsigned int ui_type;
ui_type calc( char ch, ui_type ui ) {

// ...
// :   T1
ui_type loc1 = sum( ch, ui );

// :    
// T1  T3 -  unsigned int, T2 -  char
ui_type loc2 = sum< ui_type, ui_type >( ch, ui );
}

        T1,   T2  T3,     
   .
           ,  
   . ,       
  ,    :

// : T3 -  unsigned int
// T3    ui
ui_type loc3 = sum< ui_type, char >( ch, ui );

// : T2 -  char, T3 - unsigned int
// T2  T3    pf
ui_type (*pf)( char, ui_type ) = &sum< ui_type >;

// :     
ui_type loc4 = sum< ui_type, , ui_type >( ch, ui );

    ,       , 
  ; ,    . 
        
       C++.
          sum()   
    manipulate().     
10.2,  ,     sum(),   
   manipulate().     sum(),  
  . ,  manipulate() .
         .
      :   ,
   sum(), , ,   
  manipulate(). :

++   493

template <class T1, class T2, class T3>
T1 sum( T2 op1, T3 op2 ) { /* ... */ }
void manipulate( int (*pf)( int,char ) );
void manipulate( double (*pf)( float,float ) );
int main()
{
// :     sum:
// int sum( int,char )  double sum( float, float )?
manipulate( &sum );
//    
// double sum( float, float )
// : void manipulate( double (*pf)( float, float ) );
manipulate( &sum< double, float, float > );
}

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

 10.6

     ,      
.

 10.7

         sum():

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

        ? ?

double dobj1, dobj2;
float fobj1, fobj2;
char cobj1, cobj2;

(a) sum( dobj1, dobj2 );
(b) sum<double,double,double>( fobj1, fobj2 );
(c) sum<int>( cobj1, cobj2 );
(d) sum<double, ,double>( fobj2, dobj2 );

++   494

10.5.    

           
.      . ,  
 :

template <typename Type>
Type min( Type t1, Type t2 )
{
return t1 < t2 ? t1 : t2;
}

    min(),   . ,   
 , :

int i, j;
double dobj = min( i, j );

   min()    .
      .     
,           ?
,     min()     c
    dobj?     
 ,       (inline) ?
        , 
    ?
       ,      C++ 
 ,      
   .  C++    :  
    .       
  .

10.5.1.    

            ,  
 .      ,   
 .        . :

// model1.h
//   :
//      
template <typename Type>
Type min( Type t1, Type t2 ) {
return t1 < t2 ? t1 : t2;
}

++   495

         ,   
min():

//    
//   
#include "model1.h"
int i, j;
double dobj = min( i, j );

            
.   ,      min() 
    ,     ? . 
   ,  min()       .
       ,  
  .   ,  -  
  min()  . (   ,  
    ,      
.        
   .)
            
.     ,   
        .  , 
  ,        
 .  ,       
        .
        
  . ,    .

10.5.2.    

            ,
        , ..   
   ,      (non-inline) .
:

// model2.h
//   
//     
template <typename Type> Type min( Type t1, Type t2 );
// model2.C
//  
export template <typename Type>
Type min( Type t1, Type t2 ) { /* ... */ }

   ,     min(),  
   :

++   496

// user.C
#include "model2.h"
int i, j;
double d = min ( i, j ); // :   

       min()     user.c, 
min(int,int)  .     min()   
 .   ,  ?    
  model2.c,  ,     min() 
  export.  ,  min()  .
 export  ,     
      .    
 ,        .
          template  
    export.   ,  
          
    .   export  
,         min() 
       .
    ,         ,
   ,   
        ,  
       . 
    ,  ,  
      ,  
       .
     export   ,    ,
 . ,   min()  model2.h   .
              
.  ,       , 
  ,        
.       :

       , ,   
     ,    ;
             
     ,       
      ;
           
     ,   .

      ,     
      . 
        ,  
      .
            
    ,      
 ,        .   

++   497

   ,  ,  ,  
  :       
,       C++. (  
, Inside C++ Object Model,    ,
     C++,     Edison Design
Group.)
             
,       , 
    .

10.5.3.   

            
  ,     .  ,
,  ,      ,   
 ,        
   .     (
)        
.             
       , 
 .
         ,    :
      .     
  ,      .
    ,    ,  
.    C++     ,
   ,   .
          template  
 ,      .  
sum(int*, int):

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

         int*.     
           
 .
           ,   
 .     ,     
:

++   498

#include <vector>
template <typename Type>
Type sum( Type op1, int op2 ); //  
//  typedef  vector< int >
typedef vector< int > VI;
// : sum()  
template VI sum< VI >( VI , int );

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

 10.8

       ,   C++. , 
      .

 10.9

      sum():

template <typename Type>
Type sum( Type op1, char op2 );

            
string?

10.6.    

        ,      
,      .    
   ,     ,
   .    , 
,      . , , 
   max():

++   499

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

          const char*,  
   ,    
       C,      .  
      
.
         ,    
 template     <>,    
 .    , ,  
 ,      .    
max(const char*, const char*)   :

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

   ,      
const char*      max(const char*, const char*). 
   max()     const char* 
 .      
    ,   .  
 :

#include <iostream>
//       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;
}

++   500

        ,   . ,
  max(const char*, const char*)   :

//     
template< > PCC max< PCC >( PCC, PCC );

           
  template       <>.  ,  
      :

// :   
//  template<>
PCC max< PCC >( PCC, PCC );
//   
template<> PCC max< PCC >;

         ,    
  :

// :   const char*    
template<> PCC max( PCC, PCC );

        sum()  :

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 );

     template<>       
. :

++   501

//   
template <class T>
T max( T t1, T t2 ) { /* ... */ }
// :   
const char* max( const char*, const char*);

          .  
         ,
     .  
,   ,   .
          ?      10.3,
    ,   ,
     ,    
    ,     
  .        ,  
  :       
    .   
   .       , 
      . (  10.8
    ;   ,   
   ,     ,  
,   .)
        ,   
,   .      sum() 
   .     ,
   . ,  sum()  ,     , 
    .
             .
   :

#include <iostream>
#include <cstring>

//   
template <class T>
T max( T t1, T t2 ) { /* ... */ }

int main() {
//  
// const char* max< const char* >( const char*, const char* );
const char *p = max( "hello", "world" );

cout << "p: " << p << endl;
return 0;
}

//  :   const char *:
//      
typedef const char *PCC;
template<> PCC max< PCC >(PCC s1, PCC s2 ) { /* ... */ }

++   502

       max(const char*, const char*) 
  .     , 
       . 
         ,
         .  
       max(const
char*, const char*),     .
        ,    
      ,    . 
        
,         . 
 :

// --------- max.h -------
//   
template <class Type>
Type max( Type t1, Type t2 ) { /* ... */ }

// --------- File1.C -------
#include <iostream>
#include "max.h"
void another();

int main() {
//  
// const char* max< const char* >( const char*, const char* );
const char *p = max( "hello", "world" );

cout << "p: " << p << endl;
another();
return 0;
}

// --------- File2.C -------
#include <iostream>
#include <cstring>
#include "max.h"

//     const char*
typedef const char *PCC;
template<> PCC max< PCC >( PCC s1, PCC s2 ) { /* ... */ }

void another() {
//  
// const char* max< const char* >( const char*, const char* );
const char *p = max( "hi", "again" );

cout << " p: " << p << endl;

return 0;
}

        .   File1.C   
 max(const char*, const char*).    
   .   File2.C  

++   503

,     max("hi", "again")    .
        max(const char*, const char*) 
  ,   ,   
.        
   max(const char*, const char*)  File1.C.
        ,    
 max(const char*, const char*)    ,  
  max()    const char*,   
    "max.h"       , 
   max():

// --------- max.h -------
//   
template <class Type>
Type max( Type t1, Type t2 ) { /* ... */ }

//      const char*
typedef const char *PCC;
template<> PCC max< PCC >( PCC s1, PCC s2 );

// --------- File1.C -------
#include <iostream>
#include "max.h"
void another();

int main() {
// 
// const char* max< const char* >( const char*, const char* );
const char *p = max( "hello", "world" );

// ....
}

 10.10

      count()     
  .   .   
    double, int  har.  
  count()   .

10.7.    

       .     
    min():

++   504

//    Array
// (.  2.4)

template <typename Type>
class Array( /* ... */ };

//     min()
template <typename Type>
Type min( const Array<Type>&, int ); // #1

template <typename Type>
Type min( const Type*, int ); // #2

template <typename Type>
Type min( Type, Type ); // #3

  main() ,     
  :

#include <cmath>

int main()
{
Array<int> iA(1024); //  
int ia[1024];

// Type == int; min( const Array<int>&, int )
int ival0 = min( iA, 1024 );

// Type == int; min( const int*, int )
int ival1 = min( ia, 1024 );

// Type == double; min( double, double )
double dval0 = min( sqrt( iA[0] ), sqrt( ia[0] ) );

return 0;
}

   ,  ,       , 
,       .     
    . ,  
  min5()

template <typename T>
int min5( T, T ) { /* ... */ }

       ,  min5()   
 ;       ,  
        T.

++   505

int i;
unsigned int ui;
// :  T   int
min5( 1024, i );
//      :
//  T     
min5 ( i, ui );

           min5(),  
  :

template <typename T, typename U>
int min5( T, U );

          :

min5( i, ui );

    ,     :

// : :   
//  min5( T, T )  min5( T, U )
min5( 1024, i );

     min5()       ,
   .     T,  U  int.    
  ,          
.   ,    ,  
 ,     . (   
 .  10.4.) :

// :   min5( T, U )
min5<int, int>( 1024, i );

             . 
 min5(T,U)    ,    min5(T,T), 
  min5(T,U)  ,   min5(T,T) 
.      9, ,   , 
          
.        
.

++   506

          ,   
    .     
  sum(),       , 
   :

template <typename Type>
Type sum( Type*, int );
template <typename Type>
Type sum( Type, int );
int ia[1024];
// Type == int ; sum<int>( int*, int ); 
// Type == int*; sum<int*>( int*, int ); ??
int ival1 = sum<int>( ia, 1024 );

      ,      . 
   ,    
 .    Type  int,  
int*.
          ,  ,   
        ,     , , ,
T*  T   ,        
    ,    
. ,   sum(Type*, int)   
       
.       sum(Type, int)   
     .   sum(Type*,
int)     ,  , ..  
,  ,      .

10.8.     A

       ,      . 
,           
:

//  
template <class Type>
Type sum( Type, int ) { /* ... */ }
//   ( )
double sum( double, double );

       sum(),     
  ,        
 ,      . ( 
     ,    9.)
  :

++   507

void calc( int ii, double dd ) {
//   :   
//   ?
sum( dd, ii );
}

        sum(dd,ii)  ,  
,   ?     ,   
  .      
-     , 
    .
              
   ,     .    
 ,       . ( 
   10.3.)        Type
     dd.   
  double,    -  
sum(double, int).  ,      :
    sum(double, int)   
sum(double, double).
      ,   ,   
,       .
            
  . ,    ,  
  ,     
    . (  9.3 
 ,     .) 
      sum(double, int),
     sum(double, double). ,   
.
      ,    
     .     
 :
        sum(double, int):

          ,   
       double, ..    ;
         ,    
      int, ..   .

     sum(double, double):

          ,   
       double   ;
            int,  
       double, ..      
     .

++   508

       ,     . 
       . 
  (  )   sum(double, int).
   ,   ,     
,      .   
    ,      .
   ,    sum()   :

//  
template <class T>
int sum( T*, int ) { ... }

           ,  
   double     
 T*.         
,      , ..  
    sum(double, double).   
 ,         double.
         ,     
?   ,   ,   
,    . :

//   
template <class Type> Type sum( Type, int ) { /* ... */ }

//    Type == double
template<> double sum<double>( double,int );

//  
double sum( double, double );

void manip( int ii, double dd ) {
//     sum<double>()
sum( dd, ii );
}

      sum()  manip()     
,   sum(double,int),   
,      .     
,    .     
,       
 ,        .
           .
   ,     ,  
    :

++   509

//   
template <class Type>
Type min( Type, Type ) { /* ... */ }

//    Type == double
template<> double min<double>( double, double );

void manip( int ii, double dd ) {
// :    ,
//  -   
min( dd, ii );
}

     min()    double.  
     -.   
 min()  ,   ,   Type
     ,  :  
   double,     int.    
,       ,  
min(double, double) .    - , 
 .
       10.6,      
       
,   .    min(int,int)  
 ,     min(), ,  , ,
,      template<>:

//   
template <class T>
T min( T, T );
//   min(int,int)
int min( int, int ) { }

         ,   ,
  .       min(ai[0],99)
  int.       :  min(int,int) 
          
 :

int ai[4] = { 22, 33, 44, 55 };
int main() {
//    min( int, int )
min( ai[0], 99 );
}

        .  ,  
,   ,    ,  
      min(int,int).

++   510

       ,     :  
,       ,   
    .        .
    ,     
min(int,int),       :

//  
template <class T>
T min( T, T ) { ... }

//   ,    
int min( int, int );

int ai[4] = { 22, 33, 44, 55 };
int main() {
//  : min( int, int )  
min( ai[0], 99 );
}

      ,       
  ,   ? , 
          
       .
    ,      
 ,       
.  , ,    
 .
   ,       
min<int>(int,int). ,        
min()     ,   . - ,
   ,     
  min<int>(int,int)     .  
    ,    ,
 ,       ,
.   ,   ,  
    min(int,int)    
      :

++   511

//   
template <class Type>
Type min( Type t1, Type t2 ) { ... }

int ai[4] = { 22, 33, 44, 55 };
short ss = 88;

void call_instantiation() {
// :     -
min( ai[0], ss );
}

//  
int min( int a1, int a2 ) {
min<int>( a1, a2 );
}

int main() {
call_instantiation() {
//   
min( ai[0], ss );
}

     min(ai[0],ss)  call_instantiation    -.
     min() ,   
 Type        .
,   .     min(ai[0],ss) 
main()     min(int, int).  
        ,
           
 .        ,  
 .
       ,   ,
         , 
,     :

  1.   -.
           ,   . 
            ,  
      -    , 
         ,   .
  2.     (.  9.3).
       -   ,  
         .
  3.    (.  9.3).
     a.     ,   .
     b.   ,     ,
          .
  4.  ,       
     (.  9.3).
     a.     ,   .

++   512

     b.     .

       . ,     
   .     double:

template <class Type>
Type max( Type, Type ) { ... }
//  
double max( double, double );

       max().    ,      
?

?
int main() {
int ival;
double dval;
float fd;
// ival, dval  fd  
max( 0, ival );
max( 0.25, dval );
max( 0, fd );
}

       :

  1. max(0,ival).     int.     :
         max(int, int)   
     max(double, double).    
      ,    ;
  2. max(0.25,double).     double.    
     :    max(double, double)  
     max(double, double).  ,    
     .  3b ,       ;.
  3. max(0,fd).    int  float .  
        :   max(double, double). 
        ,     Type,
          , .  
            .
        ,    
          ;   .  
         ,    .

             max()? :

++   513

template <class T> T max( T, T ) { ... }
//   
char max( char, char );
double max( double, double );

           -? .

int main() {
float fd;
//      ?
max( 0, fd );
}

    3b , ,   ,   
 .         ,  
     :    
    .  , 
,     .

 10.11

       :

template <class Type>
Type max( Type, Type ) { ... }

int main() {
int ival;
double dval;
float fd;
max( 0, ival );
max( 0.25, dval );
max( 0, fd );
double max( double, double );
}

           
  :

   template <> char max<char>* char, char ) { ... }

            max() 
main().

,   main()   :

++   514

int main() {
// ...
max( 0, 'j' );
}

         ? ?

 10.12

   ,        , 
    :

int i; unsigned int ui;
char str[24]; int ia[24];
template <class T> T calc( T*, int );
template <class T> T calc( T, T );
template<> chat calc( char*. int );
double calc( double, double );

   ,         
  .     - 
 ; ,      .

(a) cslc( str, 24 ); (d) calc( i, ui );
(b) calc( is, 24 ); (e) calc( ia, ui );
(c) calc( ia[0], 1 ); (f) calc( &i, i );

10.9.      

           
  ,       .
        :

template <typename Type>
Type min( Type* array, int size )
{
Type min_val = array[0];
for (int i = 1; i < size; ++i)
if ( array[i] < min_val )
min_val = array[i];
print( "Minimum value found: ");
print( min_val );
return min_val;
}

     min()   array  min_val    ,
   Type   ,    

++   515

size  int     . ,  array 
min_val    .   ,   
    ,    size    .
      min_val ,    ,   
  min_val  . ,   print()  
  print(min_val)?    int?  float?   
,    ,     
   ,   min_val?     ,  ,
   print(min_val)    .
           min(),    
 . ,  ,     
 print( "Minimum value found: ").     . 
  print()         , 
     .
     7  ,   C++       .  
 ,   ,  ,    
?      print()    
  min()?     ,   
. ,     ,   
   .     
min() .  

print( "Minimum value found: ");

    ,   print()    
    .    , 
  print()   min():

// ---- primer.h ----

//   :
//  min()  print( const char * )
void print( const char * );

template <typename Type>
Type min( Type* array, int size ) {

// ...

print( "Minimum value found: ");
print( min_val );

return min_val;
}

     ,   print(),    min_val,
  ,    ,     .  
,   print()     print(min_val),  
min_val   .

++   516

         print(),   
print(min_val)?   . :

#include <primer.h>
void print( int );

int ai[4] = {12, 8, 73, 45 };

int main() {
int size = sizeof(ai) / sizeof(int);
//  min( int*, int )
min( &ai[0], size );
}
 
   main()      min(int*,int).  
 Type  int,    min_val, ,  int.
   print(min_val)      int.
 ,   min(int*,int),  ,  
   print()   int.      
 .    print(int)     
min(int*,int),       .
            . 
 ,     ,  ,  , 
,   .
       ?  , ,     
?
       , , ,     
,      . ,   min()  
 ,        . ,
  min()       
.        
 <primer.h>.    print(const char*),   
 min()   .  ,  
 min()   print()   .  
   .  ,    ,
    ,        
, ..   ,        
   <primer.h>.
           ,    
,        .   , 
   .      
:

++   517

// ---- primer.h ----
template <typename Type>
Type min( Type* array, int size )
{
Type min_val = array[0];
// ...
// :  print( const char* )  
print( "Minimum value found: " );

// :    
print( min_val );
// ...
}

// ---- user.C ----
#include <primer.h>

//   print( const char* ) 
void print( const char* );
void print( int );

int ai[4] = {12, 8, 73, 45 };

int main() {
int size = sizeof(ai) / sizeof(int);
//  min( int*, int )
min( &ai[0], size );
}

     print( const char* )  user.C    , 
  .    ,   
min(int*,int),        
print("Minimum value found: "),       
.          
,       ,  
    .    
  ,   ,   , 
      .
     ,     - ,   
,   ,    
<primer.h>.  ,    ,   
,      . , 
     SmallInt     
min()   <primer.h>      
  SmallInt.
      min()     SmallInt 
  Type   SmallInt. , min_val 
  min()    .    
 print(min_val)?

++   518

// ---- user.h ----
class SmallInt { /* ... */ }
void print( const SmallInt & );

// ---- user.C ----
#include <primer.h>
#include "user.h"
SmallInt asi[4];

int main() {
//     asi
//  min( SmallInt*, int )
// int size = sizeof(asi) / sizeof(SmallInt);
min( &asi[0], size );
}

    :  ,      print(const
SmallInt &).  ,    <primer.h>,
.     ,   , 
 ,    ,     ,
   .    ,  ,
    SmallInt,     
  ,       SmallInt.
     ,    ,  
.     ,   ,  
   ,    .   
         , 
  . ,  
min(SmallInt*,int)     main()   
 :

// ...
int main() {
// ...
//  min(SmallInt*,int)
min( &asi[0], size );
}
//   min(SmallInt*,int)
//       :
SmallInt min( SmallInt* array, int size )
{ /* ... */ }

    ,          ?
    ?   :  , ,
?     SmallInt  ,   
print(const SmallInt &)     
min(SmallInt*,int):

++   519

#include <primer.h>
void another();

SmallInt asi[4];

int main() {
//     asi
int size = sizeof(asi) / sizeof(SmallInt);
min( &asi[0], size );
another();
// ...
}
//   ?

void another() {
int size = sizeof(asi) / sizeof(SmallInt);
min( &asi[0], size );
}

//  ?

           ,
    .   
   ,     .  ,  
         ,
   ,     , 
 .       , 
     :

#include <primer.h>
// user.h  ,   
#include "user.h"
void another();

SmallInt asi[4];

int main() {
// ...
}
//    min(SmallInt*,int)

void another() {
// ...
}
//    min(SmallInt*,int)

          ? ,  ,
  another()    ,  main()?  
    ,     
.       ,     
     "user.h"    , 
  .   ,  
min(SmallInt*,int)       print(const
SmallInt &)    ,     
.

++   520

 10.13

          . , 
      ,  
 ,   .

 10.14

        display  SIZE  
max(LongDouble*,SIZE)?

// ---- exercise.h ----
void display( const void* );
typedef unsigned int SIZE;

template <typename Type>
Type max( Type* array, SIZE size )
{
Type max_val = array[0];
for ( SIZE i = 1; i < size; ++i )
if ( array[i] > max_val )
max_val = array[i];

display( "Maximum value found: " );
display( max_val );

return max_val;
}
// ---- user.h ----
class LongDouble { /* ... */ };
void display( const LongDouble & );
void display( const char * );
typedef int SIZE;

// ---- user.C ----
#include <exercize.h>
#include "user.h"

LongDouble ad[7];

int main() {
//     ad
//  max( LongDouble*, SIZE )
SIZE size = sizeof(ad) / sizeof(LongDouble);
max( &ad[0], size );
}

10.10.      

        ,      
  (.      8.5  8.6).  
   ,        , 
    .     
       , 
 using-:

++   521

// ---- primer.h ----
namespace cplusplus_primer {
//      
template <class Type>
Type min( Type* array, int size ) { /* ... */ }
}

// ---- user.C ----
#include <primer.h>
int ai[4] = { 12, 8, 73, 45 };

int main() {
int size = sizeof(ai) / sizeof(ai[0]);

// :  min()  
min( &ai[0], size );

using cplusplus_primer::min; // using-
// :   min()    cplusplus_primer
min( &ai[0], size );
}

    ,     ,   
,       ? ( 
    10.6.) ,    
min(),   cplusplus_primer,     
   SmallInt.   ,   
   ,      :

if ( array[i] < min_val )

         SmallInt     <.
     ,       SmallInt
( ,       15). , 
      min(),   
 compareLess()     .   :

//    SmallInt
//  true,  parm1  parm2
bool compareLess( const SmallInt &parm1, const SmallInt &parm2 );

        ?     ,
     SmallInt  . 
   ,      ,   8-
  unsigned char, ..  0  255.  
  ,        . 
        ,  unsigned char. 
SmallInt   :

++   522

class SmallInt {
public:
SmallInt( int ival ) : value( ival ) {}
friend bool compareLess( const SmallInt &, const SmallInt & );
private:
int value; // 
};

          value,      
SmallInt.       ival:

//   SmallInt
SmallInt( int ival ) : value( ival ) {}

          value  ival.
          :    
 compareLess()?     value   
 SmallInt:

//  true,  parm1  parm2
bool compareLess( const SmallInt &parm1, const SmallInt &parm2 ) {
return parm1.value < parm2.value;
}

   , ,   value  .    
   ,     SmallInt   
   ?       SmallInt,
 ,    compareLess()   
(friend).     ,     
. (     15.2.)
         min().   
  compareLess().

//  min()    SmallInt
template<> SmallInt min<smallInt>( SmallInt* array, int size )
{
SmallInt min_val = array[0];
for (int i = 1; i < size; ++i)
//     compareLess()
if ( compareLess( array[i], min_val ) )
min_val = array[i];
print( "Minimum value found: " );
print( min_val );
return min_val;
}

++   523

        ? ,  :

// ---- primer.h ----
namespace cplusplus_primer {
//      
template <class Type>
Type min( Type* array, int size ) { /* ... */ }
}

// ---- user.h ----
class SmallInt { /* ... */ };
void print( const SmallInt & );
bool compareLess( const SmallInt &, const SmallInt & );

// ---- user.C ----
#include <primer.h>
#include "user.h"

// :     cplusplus_primer::min()
template<> SmallInt min<smallInt>( SmallInt* array, int size )
{ /* ... */ }
// ...

    ,    .      
    ,    .  
   min()   cplusplus_primer.  
     .
   ,       .  
    cplusplus_primer   :

// ---- user.C ----
#include <primer.h>
#include "user.h"

namespace cplusplus_primer {
//   cplusplus_primer::min()
template<> SmallInt min<smallInt>( SmallInt* array, int size )
{ /* ... */ }
}
SmallInt asi[4];

int main() {
//     asi   - set()

using cplusplus_primer::min; // using-
int size = sizeof(asi) / sizeof(SmallInt);
//  min(SmallInt*,int)
min( &asi[0], size );
}

      ,      
     :   
  .

++   524

// ---- user.C ----
#include <primer.h>
#include "user.h"

//   cplusplus_primer::min()
//   
namespace {
template<> SmallInt cplusplus_primer::
min<smallInt>( SmallInt* array, int size )
{ /* ... */ }
// ...

    ,  ,   ,  
 ,    ,      
  ,     .

 10.15

       <exercise.h>   10.14 
  cplusplus_primer.     main(),  
   max(),   cplusplus_primer?

 10.16

       10.14, ,   
 <exercise.h>     cplusplus_primer. , 
    max()    
LongDouble. ,     
compareGreater()      LongDouble,  :

//     LongDouble
//  true,  parm1  parm2
bool compareGreater( const LongDouble &parm1,
      const LongDouble &parm2 );

     LongDouble   :

class LongDouble {
public:
LongDouble(double dval) : value(ival) {}
friend bool compareGreater( const LongDouble &,
const LongDouble & );
private:
double value;
};

      compareGreater()   max(),  
  .    main(),   
 ad,     max(),   
. ,    ad,   
    cin.

++   525

10.11.   

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

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()  swap().   
  ,      
 ,       sort().
min()          
 :

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

swap()          :

++   526

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";
}

             
      Array.h    
 Array.
           .  sort()
     double,  int   . 
 :

++   527

#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;
}

       ,     ( 
    ):

   sort array of doubles (size == 10)
   < 1.7 5.7 11.7 14.9 15.7 19.7 26.7
      37.7 48.7 59.7 61.7 >

   sort array of ints (size == 16)
   < 61 87 154 170 275 426 503 509 512
      612 653 677 703 765 897 908 >

   sort array of strings (size == 11)
   < "a" "falling" "heavy" "left" "police" "snow"
      "station" "the" "they" "was" "when" >

++   528

      ,     C++ (  
12),     min()  swap().   12  ,  
.
