Click here to Skip to main content
13,829,149 members
Click here to Skip to main content
Add your own
alternative version


39 bookmarked
Posted 11 Jun 2003

Fun With Templates: Part 1

, 11 Jun 2003
Rate this:
Please Sign up or sign in to vote.
Explores some of the lesser known features of C++ templates.


Like many of the features of C++, template classes are mostly used for the immediate task that they were designed for, giving programmers the ability to create re-usable classes which are abstracted from the type that they are designed to work on. It is a little known fact that templates can be applied to almost any token that appears in the class definition, which opens up some interesting possibilities.

This is also my first foray into the world of Code Project article writing, so any feedback would be most appreciated. No example code has been supplied, the reason for this being that the focus of this article is the design principles more than a specific piece of code.

Using templates to specify parent classes

Did you know you can use templates to specify what class your template class inherits from?

Consider the following piece of code:

template <class Parent> 
class MyClass : public Parent
    void Foo();

Simple. By specifying Parent as a template parameter, you can now instantiate the class by specifying the parent class in the declaration as follows:

MyClass<CWnd> m_MyWndDerivedClass

m_MyWndDerivedClass is now an instantiation of MyClass, which in turn derives its behavior from CWnd. By changing the template parameter you can change what class MyClass inherits from on the fly. This means any behavior defined in MyClass can be applied to any class it inherits from. Kind of polymorphism in reverse, albeit not as powerful. Of course it is important to make sure that your class has member functions and variables that will not conflict with and foreseeable parent classes, so it would be a good idea to add an additional identifier to all variable/function names--such as MyClass_Init()

So what use is this? The possibilities are endless. But there is one especially good reason why this functionality is of great use, and that is when you begin to explore policy classes.

Policy Class Systems

Policy Class Systems are built upon the principal that, instead of defining concrete classes which have a predetermined set of behaviors, you actually design smaller "task related" classes named "Policies". Whenever there are multiple methods of performing a task, a policy class could be used to reflect the behavior. A compound class can then be constructed by the end-user of your library using any combination of the available policies. For example, a compound class could be composed of three main policies: A "Creation Policy", which handles how the object is created, where it is created, how memory was allocated, and so on and so forth; an "Initialization Policy", which could specify how the class is prepared for use, whether all the values are set to 0, whether the class should read data from a file, and so forth; the final policy could be a "Functionality Policy", which may specify whether the class should add a record to a database, send an e-mail to someone, or whatever. Truth be told, a policy based class would never have such a generalized policy as "what it actually does", but it will serve well as an example.

So how does one go about creating policies?

First off you need to decide what policies are relevant to the class. In the above example, I described three policies: "Creation", "Initialization" and "Functionality". A policy is declared as a standard templated class as follows:

template <class T> 
class CreationNew    
    static T* Create()
        return new T;

By writing this class, we have enforced a common interface that must be shared between all creation policies, which is that they must all contain a Create method, taking no parameters and returning a pointer to a T object. You can derive from an abstract interface if you wish to further enforce this interface.

This is one of the possible creation policies used by our system. CreationNew is the most basic creation method, and simply allocates memory using the new operator, and returns a pointer. Here is another:

template <class T> 
class CreationPrototype {
    static T* Create() { 

return new T(_item); };

    static T *_item;

This creation policy uses a prototype which is cloned whenever a new object of type T is requested.

The same method applies for creating the initialization policies, though their interface will differ in that they all contain a member function named Init as follows:

template <class T> class InitialisationZero 
                    { public: static void Init(T *pObj) { 
memset(pObj, 0, sizeof(T)); };

And finally the functionality policies, but as I said earlier having such a generalized policy for the functionality of your class isn't a good idea. After all you designed the class for a specific reason. Policy classes should relate to different methods of completing the same task, not different tasks altogether.

class FunctionalityHelloWorld { public: void DoSomething() { 
cout << "Hello World!"; };

Again, the common interface here is the DoSomething function, which should be present in all "Functionality Policies".

So now that we have designed all our policies, how do we create the compound class that will exploit them?

    class CreationPolicy,
    class InitPolicy,
    class FunctionalityPolicy
class CompoundClass : public CreationPolicy, 
   public InitPolicy, public FunctionalityPolicy 

There, simple, now the end-user can construct the compound class from the various policies, by using typedefs as follows:

typedef CompoundClass< CreationNew<MyClass>, 
   FunctionalityHelloWorld > MyCompoundClass;
typedef CompoundClass< CreationPrototype<MyClass>, 
  FunctionalitySendMail > MyOtherCompoundClass;

MyCompoundClass will now have three functions: Create, Init, and DoSomething, each of which is tailored to exactly how the user wants them to behave. By specifying MyClass in the template parameters, we can also specify what class the compound class works with. This is extremely useful for creating object factories and the like, especially when typelists are used (more about that another time).

But supposing you already know what class the CompoundClass is to work with? In that case, having to explicitly specify the class in a template parameter is just more clutter to the end-user. This is where "template template parameters" come in. No, that wasn't a typo.

Consider the following:

    template < class Created > class CreationPolicy
class CompoundClass : public CreationPolicy<MyClass>

Yikes, nested templates!

Indeed, by including this additional template declaration we allow the compound class to specify the template parameter itself, allowing us to declare the typedefs like this:

typedef CompoundClass< CreationNew, InitialisationZero, 
  FunctionalityHelloWorld > MyCompoundClass;
typedef CompoundClass< CreationPrototype, InitialisationZero, 
  FunctionalitySendMail > MyOtherCompoundClass;

Much neater.

Hopefully this will give an insight into the power of policy classes, as they provide a great deal of flexibility, and are not as restrictive in their use as some of the more standard OOP paradigms.

That's it for my first article. Short, yes, but hopefully it's opened a few eyes to some of the more obscure, and useful, uses for templates.

In my next article, I will be exploring more weirdness with templates, 'cause I'm like that.

Further reading

  • Modern C++ Design, by Andrei Alexandrescu, discusses Policy Class Systems along with many other "I didn't know you could do that!" C++ gems, and I strongly recommend it.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Systems Engineer
United Kingdom United Kingdom
My name is Chris Simpson and I'm great. If you like that sort of thing.

You may also be interested in...

Comments and Discussions & Pin
TW13-Jun-03 4:00
memberTW13-Jun-03 4:00 
QuestionCompiler recommendations? Pin
dog_spawn12-Jun-03 11:53
memberdog_spawn12-Jun-03 11:53 
AnswerRe: Compiler recommendations? Pin
TW13-Jun-03 2:17
memberTW13-Jun-03 2:17 
GeneralRe: Compiler recommendations? Pin
William E. Kempf13-Jun-03 13:08
memberWilliam E. Kempf13-Jun-03 13:08 
GeneralRe: Compiler recommendations? Pin
TW14-Jun-03 2:30
memberTW14-Jun-03 2:30 
GeneralRe: Compiler recommendations? Pin
Ed Din ar Qadiyyeh9-Sep-03 21:35
memberEd Din ar Qadiyyeh9-Sep-03 21:35 
AnswerRe: Compiler recommendations? Pin
William E. Kempf13-Jun-03 13:11
memberWilliam E. Kempf13-Jun-03 13:11 
GeneralGood link Pin
dog_spawn14-Jun-03 16:46
memberdog_spawn14-Jun-03 16:46 
GeneralRe: Good link Pin
TW15-Jun-03 5:04
memberTW15-Jun-03 5:04 
That's really interesting. Could you further explain "I still use Visual Studio 2003 because nothing else works for me.".

I guess your are a student, aren't you? Smile | :)
GeneralRe: Good link Pin
dog_spawn15-Jun-03 5:32
memberdog_spawn15-Jun-03 5:32 
GeneralRe: Good link Pin
TW15-Jun-03 6:13
memberTW15-Jun-03 6:13 
AnswerRe: Compiler recommendations? Pin
dmarcombes3-Sep-03 4:56
memberdmarcombes3-Sep-03 4:56 
GeneralBoring... Pin
dog_spawn3-Sep-03 8:48
memberdog_spawn3-Sep-03 8:48 
GeneralRe: Compiler recommendations? Pin
Giles13-Sep-06 3:27
memberGiles13-Sep-06 3:27 
GeneralGreat stuff ... Pin
Maximilien12-Jun-03 5:36
memberMaximilien12-Jun-03 5:36 
GeneralRe: Great stuff ... Pin
miscwriter12-Jun-03 5:47
membermiscwriter12-Jun-03 5:47 
GeneralRe: Great stuff ... Pin
yarp12-Jun-03 6:31
memberyarp12-Jun-03 6:31 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web01 | 2.8.190114.1 | Last Updated 12 Jun 2003
Article Copyright 2003 by miscwriter
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid