C++: Template Specialization

time to read 5 min | 817 words

First, I am appalled to admit that I needed Google to remember that C++ has "using namespace std;", but after this confession, I think that we can move on and talk about one of the more interesting capabilities of C++, templates and template specialization.

Here is a simple example, you want to create all your objects through factories, but you have different rules about how each type should be created. We will assume that for 90% of the cases, you will want the default behavior, but you have to have a way to customize this. There are at least five ways to do this in C++ (that are specific to C++) that I can think of right now. Template Specialization is one of them, and the nicest in the bunch.

Here is the default factory implementation:

template<typename T> class Factory

{

public:

      static T* Create()

      {

            return new T();

      }

 

      static void Release(T t)

      {

            delete t;

      }

};

It just new / delete the object that you request. Not terribly useful, but we are staying in the realm of simple examples. Now we get to the fun part, specializing this for creating users. We want to add a user id, and we don't want this logic to be in the User class. Here is how it is done:

template<> class Factory<User>

{

public:

      static User * Create()

      {

            User *user = new User();

            user->Id = CalcNextUserId();

            return user;

      }

 

      static void Release(User* user)

      {

            delete user;

      }

};

Here is the class diagram.

 

You can use those classes like this:

Factory<vector<int> >::Create()
Factory<User>::Create()

The first line just new the object, but the second one call to a complete different class, even thought they are looking nearly identitcal. A lot of the neater tricks in c++ ( and most of the smart libraries {ATL, Boost, etc} ) are based on this feature. The example I gave here is a truly trivial one, but consider a Repository<> that is specialized for each object you are going to call, you got an instance data access strategy, and a consistent way to access it.

Now, I'm not a C++ programmer anymore, so there isn't much point in taking it deaper on the C++, this post is laying the background to the more exciting .Net work that I was doing lately, based on those pricnipals. Keep in mind the basic principals, you can define a general algorithm, and specialize it for a certain type, without affecting the API* or the way in any way, shape or form. There is tremendous power in this. I recall hearing that C++ Templates are turing complete, which means that you could literally do anything you want with them.

 Now to the .Net side. Generics and templates looks somewhat the same at first glance, but there are many differences between the two. There is a great post about the differences between generics and templates here.

That is for now, I'm going to blog shortly about how you can make use of those patterns in .Net.

* As a matter of fact, you can change the API if you want, which is really awesome.