cpptraining.dependencyinjection.dicegame.templatearguments

=Version 1= One template parameter, LoadedDie that can return two values.

=Version 2= In this version, the Dice Game takes two template parameters. Notice that because of this, we cannot put them into a vector.

//**DiceGame_TwoTemplateParametersTest.h**// code format="cpp"
 * 1) include 


 * 1) include "DiceGame_TwoTemplateParameters.h"

template class HardCodedDie { public: void roll {} int faceValue { return v1; } };

TEST_GROUP(DiceGame_TwoTemplateParameters) { };

TEST(DiceGame_TwoTemplateParameters, WinningShouldIncreaeBalance) { DiceGame_TwoTemplateParameters> diceGame; diceGame.play; LONGS_EQUAL(1, diceGame.getBalance); }

TEST(DiceGame_TwoTemplateParameters, LosingShouldDecreaseBalance) { DiceGame_TwoTemplateParameters> diceGame; diceGame.play; LONGS_EQUAL(-1, diceGame.getBalance); }

TEST(DiceGame_TwoTemplateParameters, PushShouldLeaveBalanceUnchanged) { DiceGame_TwoTemplateParameters, HardCodedDie<4>> diceGame; diceGame.play; LONGS_EQUAL(0, diceGame.getBalance); } code

//**DiceGame_TwoTemplateParameters.h**// code format="cpp"
 * 1) pragma once


 * 1) include "Die.h"
 * 2) include

template class DiceGame_TwoTemplateParameters { public: DiceGame_TwoTemplateParameters; ~DiceGame_TwoTemplateParameters; void play; int getBalance const { return balance; }

private: T1 d1; T2 d2; int balance; };

template DiceGame_TwoTemplateParameters::DiceGame_TwoTemplateParameters : balance(0) { }

template DiceGame_TwoTemplateParameters::~DiceGame_TwoTemplateParameters { }

template void DiceGame_TwoTemplateParameters::play { d1.roll; d2.roll; int total = d1.faceValue + d2.faceValue; if(total > 7) ++balance; else if(total < 7) --balance; } code

=Version 3= In this version, the LoadedDie are instead "LoadedDieWithTwoAlternatinvValues", where the two values are template parameters. The DiceGame takes one template parameter. //**DiceGame_UsingTemplatesTest.cpp**// code format="cpp"
 * 1) include 


 * 1) include "DiceGame_UsingTemplates.h"

template class LoadedDieWithTwoAlternativingValues { public: LoadedDieWithTwoAlternativingValues { values[0] = v1; values[1] = v2; }

void roll {}

int faceValue { return values[++count%2]; }

private: static int count; int values[2]; };

template int LoadedDieWithTwoAlternativingValues::count = -1;

TEST_GROUP(DiceGame_UsingTemplates) { };

TEST(DiceGame_UsingTemplates, WinningShouldIncreaeBalance) { DiceGame_UsingTemplates> diceGame; diceGame.play; LONGS_EQUAL(1, diceGame.getBalance); }

TEST(DiceGame_UsingTemplates, LosingShouldDecreaseBalance) { DiceGame_UsingTemplates<LoadedDieWithTwoAlternativingValues<3>> diceGame; diceGame.play; LONGS_EQUAL(-1, diceGame.getBalance); }

TEST(DiceGame_UsingTemplates, PushShouldLeaveBalanceUnchanged) { DiceGame_UsingTemplates<LoadedDieWithTwoAlternativingValues<3, 4>> diceGame; diceGame.play; LONGS_EQUAL(0, diceGame.getBalance); } code

//**DiceGame_UsingTemplates.h**// code format="cpp"
 * 1) pragma once


 * 1) include "Die.h"
 * 2) include

template<class T=Die> class DiceGame_UsingTemplates { public: DiceGame_UsingTemplates; ~DiceGame_UsingTemplates; void play; int getBalance const { return balance; }

private: typedef std::vector<T> DiceCollection; DiceCollection dice; int balance; };

template<class T> DiceGame_UsingTemplates<T>::DiceGame_UsingTemplates : balance(0) { dice.push_back(T); dice.push_back(T); }

template<class T> DiceGame_UsingTemplates<T>::~DiceGame_UsingTemplates { }

using namespace std; using namespace tr1; using namespace placeholders; template<class T> void DiceGame_UsingTemplates<T>::play { for_each(dice.begin, dice.end, bind(&T::roll, _1)); int total = accumulate(dice.begin, dice.end, 0, bind(plus, _1, bind(&T::faceValue, _2))); if(total > 7) ++balance; else if(total < 7) --balance; } code
 * 1) include <tr1/functional>
 * 2) include