Templates
Funktionstemplates
Beispiel für ein
Funktions-Template, das den kleineren von zwei Werten zurückgeben soll:
template< class T
> // Template-Klasse !!!
class Wuerfel
{
//...
const unsigned maxrandom_;
T zahlengenerator_;
// Template-Typ als Attribut
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <conio.h>
class Random_aus_Stdlib_geklaut
{
private:
unsigned seed_;
int random()
{
// so funktioniert
rand():
return ((( seed_ = seed_ * 214013L +
2531011L ) >> 16 ) & 0x7fff );
}
public:
Random_aus_Stdlib_geklaut(){ seed_ =
static_cast<unsigned>(time(NULL)); }
Random_aus_Stdlib_geklaut( unsigned seed ) { seed_ =
seed; }
int getNum(){ return random(); }
};
class RandomStdlib // verwendet rand()
{
private:
const unsigned int seed_;
public:
RandomStdlib():seed_(
static_cast<unsigned>(time(NULL)) ){}
int getNum() const
{
static bool seed_flag = 0;
if( !seed_flag )
{
srand( seed_ );
seed_flag = true;
}
return rand();
}
};
class RandomTestEqual // Test auf
Gleichverteilung
{
private:
int num_;
public:
RandomTestEqual() : num_(RAND_MAX - 1){};
int getNum()
{
++num_;
if( num_ >= RAND_MAX )
num_ = 0;
return num_;
}
};
template< class T_Generator > //
Template-Klasse !!!
class Wuerfel
{
private:
const unsigned maxzahl_;
const unsigned maxrandom_;
T_Generator zahlengenerator_; //
Template-Typ als Attribut
public:
Wuerfel( unsigned maxzahl ) :
maxzahl_(maxzahl),
maxrandom_(RAND_MAX-(RAND_MAX%maxzahl)) {}
unsigned wuerfelt()
{
unsigned r;
do{ r = zahlengenerator_.getNum(); }
while ( r >= maxrandom_ );
return ( r % maxzahl_ + 1 );
}
};
int main()
{
const unsigned long long Serie
= 3;
const unsigned long long Versuche = 30000000;
const unsigned
limit
= 200;
const unsigned moeglichkeiten
= 6;
Wuerfel<RandomTestEqual>
w0a( moeglichkeiten );
Wuerfel<RandomTestEqual>
w0b( 2 );
Wuerfel<RandomStdlib>
w1a( moeglichkeiten );
Wuerfel<RandomStdlib>
w1b( 2 );
Wuerfel<Random_aus_Stdlib_geklaut> w2a( moeglichkeiten );
Wuerfel<Random_aus_Stdlib_geklaut> w2b( 2 );
unsigned long long H[moeglichkeiten+1];
for( unsigned long long i=1; i<Serie+1; ++i )
{
for( unsigned j=0; j<moeglichkeiten+1; ++j )
H[j] = 0;
for( unsigned long long k=1; k<Versuche+1; ++k )
{
unsigned wurf = w1a.wuerfelt();
// hier wird gewürfelt !!!!
if( Versuche<limit
)
std::cout << wurf << " ";
++H[wurf];
}
for( unsigned c=1; c<moeglichkeiten+1; ++c )
{
std::cout << std::endl
<< c << ": " << H[c] << " " <<
std::setprecision(7)
<< 100 * static_cast<float>(H[c]) / Versuche << " %";
H[0] += H[c];
}
std::cout << std::endl << "Wuerfe
insgesamt: " << H[0] << std::endl << std::endl;
}
getch();
}
Eine besonders raffinierte und effiziente Technik
des Template-Klassen-Prinzips bietet im C++-Standard die STL.
Siehe auch: http://de.wikipedia.org/wiki/C%2B%2B-Metaprogrammierung#Potenzberechnung_mit_Hilfe_von_Metatemplates