C++ does not allow virtual function templates. I am looking for a workaround.
The benefit of template arguments is they can be evaluated at compile time, which promises a great benefit in performance. In my code at home (that would be too big here), performance really matters!
I know a similar question has been posted before, but the answers were not really satisfactory. I wanted to give a simplified example, so it is more likely I get a useful advice!
My example:
A spaceship gets hit by a weapon. For this event, we need the spaceship and its type (both known only at run time), and the weapon type (known at compile time).
For now I solved the problem like that.
Problem: code size = number of spaceships * number of weapons !!
Another workaround uses the classic OO mechanisms.
Problem: performance loss, because the weapon type is evaluated at run time.
The benefit of template arguments is they can be evaluated at compile time, which promises a great benefit in performance. In my code at home (that would be too big here), performance really matters!
I know a similar question has been posted before, but the answers were not really satisfactory. I wanted to give a simplified example, so it is more likely I get a useful advice!
My example:
A spaceship gets hit by a weapon. For this event, we need the spaceship and its type (both known only at run time), and the weapon type (known at compile time).
Code:
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;
}
For now I solved the problem like that.
Problem: code size = number of spaceships * number of weapons !!
Code:
struct Spaceship {
virtual void hit_by_missile()=0;
virtual void hit_by_laser()=0;
};
struct XWing : Spaceship {
void hit_by_missile() {
cout<<"\nX-Wing was hit by a missile";
}
void hit_by_laser() {
cout<<"\nX-Wing was hit by a laser";
}
};
struct BWing : Spaceship {
void hit_by_missile() {
cout<<"\nB-Wing was hit by a missile";
}
void hit_by_laser() {
cout<<"\nB-Wing was hit by a laser";
}
}
//-----------------------------------------------------------------------
int main()
{
Spaceship* spaceship = new XWing();
spaceship.hit_by_missile();
char s;
cin>>s;
return 0;
}
Another workaround uses the classic OO mechanisms.
Problem: performance loss, because the weapon type is evaluated at run time.
Code:
struct Spaceship {
template<class Weapon> virtual void hit()=0;
};
struct XWing : Spaceship {
void hit(Weapon* weapon) {
cout<<"\nX-Wing was hit by a "<<weapon->toString();
}
};
struct BWing : Spaceship {
void hit(Weapon* weapon) {
cout<<"\nB-Wing was hit by a "<<weapon->toString();
}
}
//-----------------------------------------------------------------------
struct Weapon {
virtual char* toString()=0;
};
struct Missile : Weapon {
char* toString() {
return "missile";
}
};
struct LaserGun : Weapon {
char* toString() {
return "laser gun";
}
};
//-----------------------------------------------------------------------
int main()
{
Spaceship* spaceship = new XWing();
Weapon* weapon = new Missile();
spaceship.hit(weapon);
char s;
cin>>s;
return 0;
}
Last edited: