I'm porting a card game application I developed in Java to C++, where the rank and suit of the card object are generic (to be able to use more than one specific set), and the card itself is generic also (to be bale to use poker cards, tarot card, etc).
I'm getting compile errors in the Dealer class (a template), which takes the card object (another template) using CodeBlocks 13.12 "codeblocks-13.12mingw-setup-TDM-GCC-481"
Card class (abstract but implements shared functionality all cards must have)
#ifndef CARD_H
#define CARD_H
#include <iostream>
#include <fstream>
#include <cassert>
using namespace std;
enum BJRank
{
Ace,
Two,
Three,
Four,
Five,
Six,
Seven,
Eight,
Nine,
Ten,
Jack,
Queen,
King,
END_OF_RANKS
};
enum GenericSuit
{
Clubs,
Diamonds,
Hearts,
Spades,
END_OF_SUITS
};
template <class U, class V>
class Card {
private:
U itsRank;
V itsSuit;
protected:
Card(U newRank = Jack, V newSuit = Spades):
itsRank(newRank), itsSuit(newSuit)
{
//s_numberPlayers++;
//cout<<"Number of cards available is: " << s_numberPlayers << "\n";
ofstream myfile ("C:/Temp/cardLogFile.txt", ios::app);
if (myfile.is_open())
{
myfile << "Card base object constructed\n";
}
}
public:
virtual ~Card()
{
ofstream myfile ("C:/Temp/cardLogFile.txt", ios::app);
if (myfile.is_open())
{
myfile << "Card base object destroyed\n";
myfile.close();
}
// if (s_numberPlayers > 0)
// s_numberPlayers--;
// cout<<"Number of cards available is: " << s_numberPlayers << "\n";
}
virtual void setRank(U newRank)
{
this->itsRank = newRank;
}
virtual void setSuit(V newSuit)
{
this->itsSuit = newSuit;
}
virtual const U getRank()
{
return this->itsRank;
}
virtual const V getSuit()
{
return this->itsSuit;
}
};
#endif
One card derived class (poker card)
#ifndef POKERCARD_H
#define POKERCARD_H
#include "Card.h"
template <class U, class V>
class PokerCard : virtual public Card <U, V> {
public:
PokerCard(): Card <U, V>() {}
PokerCard(U newRank, V newSuit): Card <U, V>(newRank, newSuit) {}
~PokerCard() {}
protected:
virtual void setRank(U newRank)
{
Card <U, V> ::setRank(newRank);
}
virtual void setSuit(V newSuit)
{
Card <U, V> ::setSuit(newSuit);
}
virtual const U getRank()
{
Card <U, V> ::getRank();
}
virtual const V getSuit()
{
Card <U, V> ::getSuit();
}
const int getValue(){return 1;}
};
#endif // POKERCARD_H
The Dealer abstract class (from which the House and players will be derived)
#ifndef DEALER_H
#define DEALER_H
#include <fstream>
#include <cassert>
#include <vector>
#include "PokerCard.h"
#include "TarotCard.h"
template < template <class U, class V> class T>
class Dealer
{
public:
Dealer() {}
Dealer(Card<U, V>* cardType) {}
virtual ~Dealer() {}
virtual const vector <Card<U, V>*> getHand()=0;
};
#endif // DEALER_H
And finally, the Dealer derived class (that creates the card pointer to poker card objects)
#ifndef DEALERHOUSE_H
#define DEALERHOUSE_H
#include "Dealer.h"
template < template <class U, class V> class T>
class DealerHouse : virtual public Dealer <T> {
private:
vector <Card<U, V>* > dealerDeck;
Card <U, V> *card;
public:
DealerHouse(): Dealer<T>()
{
for (int suitInt = Clubs; suitInt != END_OF_SUITS; suitInt++)
{
for (int rankInt = Ace; rankInt != END_OF_RANKS; rankInt++)
{
card = new T((U)rankInt, (V)suitInt);
if (card != NULL)
dealerDeck.push_back(card);
else
cout <<"ERROR, card object not created in HEAP" << "\n";
}
}
ofstream myfile ("C:/Temp/dealerLogFile.txt", ios::app);
if (myfile.is_open())
{
myfile << "Default Dealer base object constructed:" << "\n";
}
}
DealerHouse(Card<U, V>* cardType): Dealer<T>(cardType)
{
dealerDeck.push_back(cardType);
ofstream myfile ("C:/Temp/dealerLogFile.txt", ios::app);
if (myfile.is_open())
{
myfile << "Parameterized Dealer base object constructed:" << "\n";
}
}
virtual ~DealerHouse()
{
if (!dealerDeck.empty())
{
dealerDeck.clear();
}
if (card != NULL)
{
delete card;
card = NULL;
}
ofstream myfile ("C:/Temp/dealerLogFile.txt", ios::app);
if (myfile.is_open())
{
myfile << "Dealer object destroyed:" << "\n";
myfile.close();
}
}
protected:
virtual const vector <Card<U, V>*> getHand()
{
return dealerDeck;
}
};
#endif // DEALERHOUSE_H
I'm getting this compile error in Dealer.h, line "Dealer(Card* cardType) {}": CardGame\Dealer.h|16|error: 'U' was not declared in this scope| CardGame\Dealer.h|16|error: 'V' was not declared in this scope|
So I'm guessing I'm screwing the declaration of Dealer.h template arguments "template < template class T> class Dealer", and also the ones in DealerHouse.h, which follow the same syntax.
Any help with that please? I already checked the answers to similar questions Template parameters in C++ templates c++ template to template parameter how to declare template of template class
But when I try the suggested declaration in them, I get the error in DealerHouse.H that the "T" type is not recognized in "card = new T((U)rankInt, (V)suitInt);".
I appreciate any help with this, I'm really stuck with that...