I always knew C++ templates were the work of the Devil,
 and now I'm sure...
    - Cliff Click cited by Todd Veldhuisen



 Your quote here.
    - B. Stroustup



// maximum függvény

int max( int a, int b)
{
    if ( a > b )
        return a;
    else
        return b;
}

double max( double a, double b)
{
    if ( a > b )
        return a;
    else
        return b;
}

// ... és így tovább ...

// de mi van azokkal a típusokkal, amiket még nem írtunk meg?
// pl. max( date, date)




// Preprocessor Macro




#define MAX(a,b)    a > b ? a : b

MAX( x, y)*2  -->   x > y ? x : y*2


#define MAX(a,b)    ((a) > (b) ? (a) : (b))

MAX( ++x, y) -->    ++x > y ? ++x : y



// sajnos nem mindig működik, mert a C++ makró típustalan

void swap( int& x, int& y)
{
    int temp = x;   // mi lesz x típusa?
    x = y;
    y = temp;
}




template <typename T>
void swap( T& x, T& y)
{
    T temp = x;
    x = y;
    y = temp;
}



template <class T>
T max( T a, T b)
{
    if ( a > b )
        return a;
    else
        return b;
}



// a függvény template nem függvény, hanem egy gyártási eljárás!


// a példányosítás (általában) automatikus:

    double x, y = 5.1, z = 3.14;

    x = max( y, z);




// template paraméter lehet skalár is:
template <class T, T defval>
class C
{
    T   t[defval];
    //...
}


    C<int,10>   c;



A template paraméter lehet:
- konstans kifejezés
- külső szerkesztésű objektum vayg függvény címe
- (nem túlterhelt) tagra mutató pointer




// típus ekvinalencia:


C<char,10>      c1;
C<int, 10>      c2; // más típus, mint c1 
C<int, 25-15>   c3; // ugyanaz a típus, mint c2





// Példányosítás, paraméter dedukció:

    int     i = 3, j = 4, k;
    double  x = 3.14, y = 4.14, z;
    const int ci = 6;

    k = max( i, j);     // -> max(int, int)
    z = max( x, y);     // -> max(double, double)
    k = max( i, ci);    // -> max(int, int)

    z = max( i, x);     // -> hiba





template <class T, class S>
T max( T a, S b)
{
    if ( a > b )
        return a;
    else
        return b;
}


    int     i = 3;
    double  x = 3.14;

    z = max( i, x);     // ok, de..


    z == 3.0    // ??








// a paraméter dedukció fordítási időben történik


template <class R, class T, class S>
R max( T a, S b)
{
    if ( a > b )
        return a;
    else
        return b;
}


    z = max( i, x);     // error, a visszatérő értéken nem lehet
                        // kikövetkeztetni a paraméter (R) típusát 





// nem túl elegáns, de működik:
template <class R, class T, class S>
R max( T a, S b, R)
{
    if ( a > b )
        return a;
    else
        return b;
}


    z = max( i, x, 0.0);    // ok, but ugly and misleading



Explicit specializáció


// elegáns:
template <class R, class T, class S>
R max( T a, S b)
{
    if ( a > b )
        return a;
    else
        return b;
}



    z = max<double>( i, x);             // ok, visszatér: 3.14
    k = max<long, long, int>( i, x);    // long-ra és int-re konvertál
    k = max<int, int, int>( i, j);      // ok, de felesleges



Template overloading



template <class T>  T   max(T,T);
template <class R, class T, class S>    R   max(T,S);



Felhasználói specializáció (User specializations)

    char *s1 = "Hello";
    char *s2 = "world";

    cout << max( s1, s2);       // ??




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


// vagy rövidebben:

template <> const char *max( const char *s1, const char *s2) ...