For understanding patterns, this has the huge advantage of getting terminology directly, because the way you talk about them determines the way you think about them.
In particular, Area not a template class, but a class template. That is, it is a template from which classes can be generated. Area<int> is such a class (this is not an object, but, of course, you can create an object from this class in the same way as you can create objects from any other class). Another such class would be Area<char> . Note that these are completely different classes that have nothing in common except for the fact that they were created from the same class template.
Since Area not a class, you cannot extract the Rectangle class from it. You can get a class from another class (or several of them). Since Area<int> is a class, you can, for example, extract a Rectangle from it:
class Rectangle: public Area<int> {
Since Area<int> and Area<char> are different classes, you can even extract them from both at the same time (however, when accessing members from them you will have to deal with ambiguities):
class Rectangle: public Area<int>, public Area<char> {
However, you need to specify which classification to use when you define a Rectangle . This is true whether these classes are generated from the template or not. Two objects of the same class simply cannot have different inheritance hierarchies.
What you can do is make a Rectangle pattern. If you write
template<typename T> class Rectangle: public Area<T> {
You have a Rectangle template from which you can get the Rectangle<int> class that comes from Area<int> , and another Rectangle<char> class that comes from Area<char> .
Perhaps you want to have one type of Rectangle so that you can pass all kinds of Rectangle to the same function (which itself does not need to know the type of region). Since the Rectangle<T> classes created by instantiating the Rectangle template are formally independent of each other, this does not work. However, you can use multiple inheritance here:
class Rectangle // not inheriting from any Area type { // Area independent interface }; template<typename T> class SpecificRectangle: public Rectangle, public Area<T> { // Area dependent stuff }; void foo(Rectangle&); // A function which works with generic rectangles int main() { SpecificRectangle<int> intrect; foo(intrect); SpecificRectangle<char> charrect; foo(charrect); }
If it is important that your overall Rectangle derived from a common Area , you can do the same trick with Area too:
class Area { // generic Area interface }; class Rectangle: public virtual Area // virtual because of "diamond inheritance" { // generic rectangle interface }; template<typename T> class SpecificArea: public virtual Area { // specific implementation of Area for type T }; template<typename T> class SpecificRectangle: public Rectangle, // maybe this should be virtual as well, in case the hierarchy is extended later public SpecificArea<T> // no virtual inheritance needed here { // specific implementation of Rectangle for type T };