The notion of policy-based architecture is hardly new, but it is sadly underused in most practical applications. I won’t get into the whole exploration of the idea here, since that’d take a lot of space, and I mostly just want to give readers a taste of what it can do.

Here’s the basic idea. Let’s start with a simple container dependency.

class ThingWhatDoesCoolStuff { std::vector<int> Stuff; };

This clearly makes our nifty class dependent on std::vector , which is not great for people who don’t have std::vector in their acceptable tools list.

Let’s make this a bit better, shall we?

template <typename ContainerType> class ThingWhatDoesCoolStuff { ContainerType Stuff; }; // Clients do this ThingWhatDoesCoolStuff<std::vector<int>> Thing;

Slightly better, but now clients have to spell a really weird name all the time (which admittedly can be solved to great extent with a typedef and C++11 using declarations).

This also breaks when we actually write code:

template <typename ContainerType> class ThingWhatDoesCoolStuff { public: void AddStuff (int stuff) { Stuff.push_back(stuff); } private: ContainerType Stuff; };

This works provided that the container we give it has a method called push_back . What if the method in my library is called Add instead? Now we have a compiler error, and I have to rewrite the nifty class to conform to my container’s API instead of the C++ Standard Library API. So much for reuse.

You know what they say, you can solve any problem by adding enough layers of indirection! So let’s do that real quick.

// This goes in the reusable library template <typename Policy> class ThingWhatDoesCoolStuff { private: // YES I SWEAR THIS IS REAL SYNTAX typedef typename Policy::template ContainerType<int> Container; // Give us a member container of the desired type! Container Stuff; public: void AddStuff (int stuff) { using Adapter = Policy::ContainerAdapter<int>; Adapter::PushBack(&Stuff, stuff); } }; // Users of the library just need to write this once: struct MyPolicy { // This just needs to point to the container we want template <typename T> using ContainerType = std::vector<T>; template <typename T> struct ContainerAdapter { static inline void PushBack (MyPolicy::ContainerType * container, T && element) { // This would change based on the API we use container->push_back(element); } }; };

Let’s pull this apart and see how it works.

First, we introduce a template "policy" which lets us decouple our nifty class from all the things it relies on, such as container classes. Any "reusable" code should be decoupled from its dependencies. (This by no means the only way to do so, even in C++, but it’s a nice trick to have in your kit.)

The hairy parts of this are really just the syntax for it all. Effectively, our nifty class just says "hey I want to use some container, and an adapter API that I know how to talk to. If you can give me an adapter to your container I’ll happily use it!"

Here we use templates to avoid a lot of virtual dispatch overhead. Theoretically I could make a base class like "Container" and inherit from it and blah blah vomit I hate myself for just thinking this. Let’s not explore that notion any further.

What’s cool is that I can keep the library code 100% identical between projects that do use the C++ Standard Library, and projects which don’t. So I could publish my callback system exactly once, and nobody would have to edit the code to use it.

There is a cost here, and it’s worth thinking about: any time someone reuses my code, they have to write a suitable policy. In practice, this means you write a policy about once for every time you change your entire code base to use a different container API. In other words, pffffft.