I have heard that C++ class member function templates can\'t be virtual. Is this true?
If they can be virtual, what is an example of a scenario in which one would
In the other answers the proposed template function is a facade and doesn't offer any practical benefit.
The language doesn't allow virtual template functions but with a workaround it is possible to have both, e.g. one template implementation for each class and a virtual common interface.
It is however necessary to define for each template type combination a dummy virtual wrapper function:
#include
#include
#include
//---------------------------------------------
// Abstract class with virtual functions
class Geometry {
public:
virtual void getArea(float &area) = 0;
virtual void getArea(long double &area) = 0;
};
//---------------------------------------------
// Square
class Square : public Geometry {
public:
float size {1};
// virtual wrapper functions call template function for square
virtual void getArea(float &area) { getAreaT(area); }
virtual void getArea(long double &area) { getAreaT(area); }
private:
// Template function for squares
template
void getAreaT(T &area) {
area = static_cast(size * size);
}
};
//---------------------------------------------
// Circle
class Circle : public Geometry {
public:
float radius {1};
// virtual wrapper functions call template function for circle
virtual void getArea(float &area) { getAreaT(area); }
virtual void getArea(long double &area) { getAreaT(area); }
private:
// Template function for Circles
template
void getAreaT(T &area) {
area = static_cast(radius * radius * 3.1415926535897932385L);
}
};
//---------------------------------------------
// Main
int main()
{
// get area of square using template based function T=float
std::unique_ptr geometry = std::make_unique();
float areaSquare;
geometry->getArea(areaSquare);
// get area of circle using template based function T=long double
geometry = std::make_unique();
long double areaCircle;
geometry->getArea(areaCircle);
std::cout << std::setprecision(20) << "Square area is " << areaSquare << ", Circle area is " << areaCircle << std::endl;
return 0;
}
Output:
Square area is 1, Circle area is 3.1415926535897932385
Try it here