Original Post
Hi! I found a workaround for the problem of virtual template methods in C++. I would like to get some technical feedback ! Especially about the performance. The workaround uses a 'dead' argument, just to make a different signature. I'm afraid this argument might cause overhead. The following would be nice, but is not possible in C++. And this is my workaround. Same/similar problem, but without solution: virtual templated member function workaround pure virtual templated methods? Virtual templates possible? Discussion about my workaround (but not enough technical feedback) http://www.c-plusplus.de/forum/viewtopic-var-t-is-165189.html (in german) http://www.velocityreviews.com/forums/t376254-workaround-for-virtual-function-templates.html
struct Spaceship {
template<class Weapon> virtual void hit()=0; // not allowed
};
struct XWing : Spaceship {
template<class Weapon> void hit() {
cout<<"\nX-Wing was hit by a "<<Weapon::toString();
}
};
struct BWing : Spaceship{
template<class Weapon> void hit() {
cout<<"\nB-Wing was hit by a "<<Weapon::toString();
}
}
//-----------------------------------------------------------------------
struct Missile {
static char* toString() {
return "missile";
}
};
struct LaserGun {
static char* toString() {
return "laser gun";
}
};
//-----------------------------------------------------------------------
int main()
{
Spaceship* spaceship = new XWing();
spaceship.hit<Missile>();
char s;
cin>>s;
return 0;
}
Spaceship::AfraidOf<Missile> Spaceship::AfraidOf<LaserGun>
|_________________________________|
|
Spaceship::Ship
_________________________|________________________
| | | |
XWing::AfraidOf<Missile> | BWing::AfraidOf<Missile> |
| | | |
| XWing::AfraidOf<LaserGun> | BWing::AfraidOf<LaserGun>
|________________| |________________|
| |
XWing::Ship BWing::Ship struct Missile {
static char* toString() {return "missile";}
};
struct LaserGun {
static char* toString() {return "laser gun";}
};
//-----------------------------------------------------------------------
struct Spaceship {
template<class W> struct AfraidOfWeapon {
virtual void hit(W* w)=0;
};
struct Ship : AfraidOfWeapon<Missile>, AfraidOfWeapon<LaserGun> {
template<class W> void hit() {
W w;
((AfraidOfWeapon<W>*)this)->hit((W*)0);
}
};
};
//-----------------------------------------------------------------------
struct XWing {
template<class W> struct AfraidOfWeapon : virtual Spaceship::Ship {
void hit(W* w) {
cout<<"\nX-Wing was hit by a "<<W::toString();
}
};
struct Ship : AfraidOfWeapon<Missile>, AfraidOfWeapon<LaserGun> {};
};
//-----------------------------------------------------------------------
int main()
{
Spaceship::Ship* spaceship = new XWing::Ship();
spaceship->hit<Missile>();
return 0;
}