convert inheritance to templates - c++

I have C++11 project that uses inheritance. Here is small fragment:
class ICountable{
public:
virtual ~ICountable(){}
unsigned getCount() const{
return _getCount();
}
bool isEmpty() const{
return _getCount() == 0;
}
private:
virtual unsigned _getCount() const = 0;
};
Suppose we have some LinkList that inherits from ICountable and implements _getCount(). Then you can make function like this:
void doSomething(ICountable &countable){
if (countable.isEmpty())
doSomethingElse();
}
...
LinkList ll;
doSomething(ll);
This is all very good, but there must be another way to do all this:
template <typename T>
void doSomething(T countable){
if (countable.isEmpty())
doSomethingElse();
}
...
LinkList ll;
doSomething(ll); // we do not even need to add <>
Template way is faster and probably easier to implement. std::vector and std::deque are like this as well.
However, how I can avoid code duplication - function isEmpty() must be pasted in all "list things".
I can imagine preprocessor #include or...
I can imagine decorator-like class that may implements all those sugar methods and to proxy the others:
template <typename T>
class List{
T list;
public:
unsigned getCount() const{
return list.getCount();
}
bool isEmpty() const{
return list.getCount() == 0;
}
...
}
What is better inheritance or templates, if there will be no runtime polymorphism?
Is there better way to avoid code duplication?

There is a C++ feature that has not been formally added to the standard (but has been in the works for quite some time) called Concepts that would essentially let you declare your doSomething(T countable) to have the requirement that T implement a certain interface (ie, that it has an isEmpty() function). Until then, you can't avoid polymorphism if what you want is to avoid code duplication by sharing a set of common functions (re: interface) between different classes. That's one of the main reasons to use polymorphism in the first place.
With that said, you are looking for the Curiously Recurring Template Pattern like Igor Tandetnik mentioned in the comments. This allows you to share common code between classes without the runtime penalty of virtual functions (runtime polymorphism). Using CRTP lets the compiler do that stuff for you.
Using a simple base class:
template <typename T>
struct ICountable {
bool isEmpty() const { return static_cast<T*>(this)->_getCount() == 0; }
};
And then your derived list:
class LinkedList : public ICountable<LinkedList> {
int _getCount() const { return size; }
};
Any class that derives from ICountable in this way will now have an isEmpty() method that uses the implementation-specific _getCount() method without the use of virtual functions.

With templates, you just imply the interface. You write a function template and require that the type you pass in meets your criteria. In this case, just:
template <typename T>
void doSomething(T const& countable) {
if (countable.empty()) {
doSomethingElse();
}
}
All the C++ standard containers have an empty() method, and you could do worse than copy the standard interfaces for containers that you write yourself. This function already works for vector and list and string and ..., all without any dynamic dispatch overhead or without the OOP requirements of having to inherit from some interface.
Generic programming works if the types have the interface you need - they don't need to inherit from all the correct named interfaces to get them.

Related

Compile-time pure virtual functions

I've tried implementing a list container,
and decided to move some general functions
like sum() to base class, so that I can
reuse them later in other containers.
All the base support class needs are three
methods empty(), head() and tail.
I can't make those pure virtual because support
class will never be instantiated. But it still
has to use those methods to implement its own
methods like sum().
I tried something like this:
#include <iostream>
using namespace std;
template<typename T>
class StatsSupport {
public:
T sum(void) const {
if (empty()) {
return T(0);
} else {
return head() + tail()->sum;
}
}
// other methods
};
template<typename T>
class List : public StatsSupport<T> {
public:
// constructors etc.
bool empty(void) const {return head_ != NULL;}
const T& head(void) const {return *head_;}
const List<T>& tail(void) const {return *tail_;}
// other methods
private:
T* head_;
List<T> *tail_;
};
But trying to use sum() gets me compilation error
prog.cpp:8:13: error: there are no arguments to 'empty' that depend on a template parameter, so a declaration of 'empty' must be available [-fpermissive]
if (empty()) {
^
for each of empty(), head() and tail().
Any advice?
The problem is that StatsSupport cannot find the empty, head etc. functions because these neither exist in its nor in the global scope.
StatsSupport does not know about the functions that exist in the derived class.
Basically there are two ways to solve this:
Runtime polymorphism, where you add a virtual destructor to StatsSupport and add declarations for empty, head etc. which are pure virtual.
Compile time polymorphism via using CRTP as mentioned in the comments.
I will focus on the latter.
So basically StatsSupport needs to get a way to access functions of the derived class.
This can be done by adding the type of the derived class as template parameter, which is called CRTP:
template<class Derived, typename T>
class StatsSupport {
public:
T sum(void) const {
if (derived()->empty()) {
return T(0);
} else {
return derived()->head() + derived()->tail()->sum;
}
}
// other methods
private:
Derived *derived()
{
return static_cast<Derived*>(this);
}
const Derived *derived() const
{
return static_cast<const Derived*>(this);
}
};
template<typename T>
class List : public StatsSupport<List<T>, T> { // with some changes could be simplified to StatsSupport<List<T>> but this it ouf of scope of this question
I am using a function for derived instead of a member to keep the class const correct.
Of course another alternative would be a different design relying on algorithms. There you move sum and all the other functions of StatsSupport into global namesapce and would then access them like sum(my_container_instance).
A more STL like way would be to use iterators. Then you could use std::accumulate to do the summing.
That's a serious design issue: Your StatSupport defines some general functions, but relies on specifics of its child classes.
So when StatSupport gets compiled, it doesn't even know that there is some head() and tail(). That's why you get the error message
Now imagine that one day you want to define other containers that shall inherit from StatSupport, for example your own Vector or Map, or DataBase. These data structures will not have a head and a tail.
Basically there are two main orientations you may take:
define in your StatSupport some virtual functions for iterating through the data structure.
or better, use in your data structures some iterators (like they exist for standard containers) and define some template functions (sum, average, etc...) that use iterators to browse through your container.
In the latter case, you wouldn't need inheritance to benefit from generic functions.
I might miss the point of the question but will give my 5 cents to it anyway :)
The reasoning behind the solution I show below is, that often people new to OOP (in C++) think that they must use inheritance to get things done.
But especially in C++, this is but one way and often not the best way to achieve composition.
While in the majority of cases, the overhead cost of virtual functions does not really matter, the code below shows a way to yield container expansions without using inheritance and without using virtual functions. The weak point of the approach is that the "container function contract" is only implicitly visible.
template <class _X>
class ContainerTypeA < _X >
{
public:
typedef _X value_type;
typedef ContainerTypeA<_X> container_type;
const _X & Head() const
{
// return head of this containers content.
}
container_type Tail() const
{
// return the tail (all elements after the first element in a new instance.
}
bool IsEmpty() const
{
return true; // return whether or not this container is empty.
}
};
template <class _X>
class ContainerTypeB < _X >
{
public:
typedef _X value_type;
typedef ContainerTypeB<_X> container_type;
const _X & Head() const
{
// return head of this containers content.
}
container_type Tail() const
{
// return the tail (all elements after the first element) in a new instance.
}
bool IsEmpty() const
{
return true; // return whether or not this container is empty.
}
};
// Note: In stead of the class with static member functions, this could
// as well be a namespace with template-functions inside.
template < class _ContainerT >
class ContainerStats<_ContainerT>
{
static _ContainerT::value_type Sum(const _ContainerT & container)
{
// Implement sum - possibly in the recursive way you did in your question.
}
// more expansion functions...
};

Is inheriting from a template argument bad practice?

So in a recent C++ project I'm starting to find that a quick way to decouple a lot of code is to write template classes which inherit from the template argument. Here's a general example:
class BaseBehavior
{
// this class has a well defined and extensive interface, however I'll show this function as an example
virtual const std::string name() const {return "base1";};
};
class DerivedBehavior: public BaseBehavior
{
// may add functions to the interface or override any virtual in BaseBehavior
virtual const std::string name() const {return "base2";};
};
Those are two different behaviors which are then inheritable by at least two other classes
template<class T>
class ImplementBehavior1: public T
{
// an important feature is that this inherits the interface of T as well
virtual const std::string greet() const {return "hello"+name();};
};
template<class T>
class ImplementBehavior2: public ImplementBehavior1<T>
{
// now this can has T's interface as well as ImplementedBehavior's
virtual const std::string greet() const {return "good evening"+name();};
};
I used this technique (in a more useful case) in my code where essentially I almost wanted a table of behaviors. Here we can have 4 different classes with 4 different behaviors. I first noticed that this strategy could have the same benefit without templates, using polymorphic components, however my code didn't require that the implementations be dynamic at runtime, and this also decoupled a lot of code since I was able to inherit the interface without having to worry about writing a stub interface. Further it lets a lot of things happen at compile time which I'd imagine make it more efficient at runtime.
I've never seen this style SUGGESTED and it certainly looks obscure, however I've found it was the best way for my case, and I could see myself applying it to a lot of situations. I'm wondering if there are any inherent flaws with this structure which I'm missing now?
As you're asking about
"Is inheriting a template argument bad practice?"
I'd say it (as so often) totally depends on your actual use case. There might be valid uses, but more often these will apply:
The template class should be a wrapper for T, then in most cases a T member;1 variable will be the most appropriate choice.
The template class should provide some mixed in behavior2, then the classical CRTP, where T inherits a mixed in implementation will be the better choice.
There are rare cases3 for the situation mentioned in the 1st point, where it could save efforts, when simply derive T with a wrapper class, though this might introduce further problems (e.g. clashing inheritance structures).
(1)
template<typename T>
class Wrapper {
public:
void foo() { member.foo(); }
protected:
T member;
};
(2)
template<class Derived>
class MixIn {
public:
void foo() { static_cast<Derived*>(this)->doFoo(); }
protected:
MixIn() {}
void doFoo() {
// Provide a default implementation
}
};
class Impl : public MixIn<Impl> {
friend class MixIn<Impl>;
// Optionally provide a deviate implementation
// void doFoo() {
// // Optionally include the default behavior
// MixIn<Impl>::doFoo()
// }
};
(3)
template<class Base>
class Adapter : public Base {
public:
Adapter() : Base() {}
Adapter(const Adapter& rhs) : Base(rhs) {}
Adapter& operator=(const Adapter& rhs) {
Base::operator=(rhs);
return *this;
}
// Totally depends on what needs to be adapted
};
Don't worry:
Plain inheritance is almost always the wrong choice. That topic doesn't correlate with templates and meta-programming in particular or primarily.
I guess it depends on the real usage of your concept if it's the best way or not, but using template classes to do generic tasks at compiletime is a pretty common way.
Atm I'm using a library at work for processing medical images wich is completely template based and work quite fine, so don't mind your concept and go ahead!
Cheers Usche
PS.: here is the template based lib: http://www.itk.org/ITK/help/documentation.html

What is an appropriate interface for dealing with meta-aspects of classes?

I'm looking for some advice of what would be an appropriate interface for dealing with aspects about classes (that deal with classes), but which are not part of the actual class they are dealing with (meta-aspects). This needs some explanation...
In my specific example I need to implement a custom RTTI system that is a bit more complex than the one offered by C++ (I won't go into why I need that). My base object is FooBase and each child class of this base is associated a FooTypeInfo object.
// Given a base pointer that holds a derived type,
// I need to be able to find the actual type of the
// derived object I'm holding.
FooBase* base = new FooDerived;
// The obvious approach is to use virtual functions...
const FooTypeInfo& info = base->typeinfo();
Using virtual functions to deal with the run-time type of the object doesn't feel right to me. I tend to think of the run-time type of an object as something that goes beyond the scope of the class, and as such it should not be part of its explicit interface. The following interface makes me feel a lot more comfortable...
FooBase* base = new FooDerived;
const FooTypeInfo& info = foo::typeinfo(base);
However, even though the interface is not part of the class, the implementation would still have to use virtual functions, in order for this to work:
class FooBase
{
protected:
virtual const FooTypeInfo& typeinfo() const = 0;
friend const FooTypeInfo& ::foo::typeinfo(const FooBase*);
};
namespace foo
{
const FooTypeInfo& typeinfo(const FooBase* ptr) {
return ptr->typeinfo();
}
}
Do you think I should use this second interface (that feels more appropriate to me) and deal with the slightly more complex implementation, or shoud I just go with the first interface?
#Seth Carnegie
This is a difficult problem if you don't even want derived classes to know about being part of the RTTI ... because you can't really do anything in the FooBase constructor that depends on the runtime type of the class being instantiated (for the same reason you can't call virtual methods in a ctor or dtor).
FooBase is the common base of the hierarchy. I also have a separate CppFoo<> class template that reduces the amount of boilerplate and makes the definition of types easier. There's another PythonFoo class that work with Python derived objects.
template<typename FooClass>
class CppFoo : public FooBase
{
private:
const FooTypeInfo& typeinfo() const {
return ::foo::typeinfo<FooClass>();
}
};
class SpecificFoo : public CppFoo<SpecificFoo>
{
// The class can now be implemented agnostic of the
// RTTI system that works behind the scenes.
};
A few more details about how the system works can be found here:
► https://stackoverflow.com/a/8979111/627005
You can tie dynamic type with static type via typeid keyword and use returned std::type_info objects as means of identification. Furthermore, if you apply typeid on a separate class created specially for the purpose, it will be totally non-intrusive for the classes you are interesed in, althought their names still have to be known in advance. It is important that typeid is applied on a type which supports dynamic polymorphism - it has to have some virtual function.
Here is example:
#include <typeinfo>
#include <cstdio>
class Base;
class Derived;
template <typename T> class sensor { virtual ~sensor(); };
extern const std::type_info& base = typeid(sensor<Base>);
extern const std::type_info& derived = typeid(sensor<Derived>);
template <const std::type_info* Type> struct type
{
static const char* name;
static void stuff();
};
template <const std::type_info* Type> const char* type<Type>::name = Type->name();
template<> void type<&base>::stuff()
{
std::puts("I know about Base");
}
template<> void type<&derived>::stuff()
{
std::puts("I know about Derived");
}
int main()
{
std::puts(type<&base>::name);
type<&base>::stuff();
std::puts(type<&derived>::name);
type<&derived>::stuff();
}
Needless to say, since std::type_info are proper objects and they are unique and ordered, you can manage them in a collection and thus erase type queried from the interface:
template <typename T> struct sensor {virtual ~sensor() {}};
struct type
{
const std::type_info& info;
template <typename T>
explicit type(sensor<T> t) : info(typeid(t))
{};
};
bool operator<(const type& lh, const type& rh)
{
return lh.info.before(rh.info);
}
int main()
{
std::set<type> t;
t.insert(type(sensor<Base>()));
t.insert(type(sensor<Derived>()));
for (std::set<type>::iterator i = t.begin(); i != t.end(); ++i)
std::puts(i->info.name());
}
Of course you can mix and match both, as you see fit.
Two limitations:
there is no actual introspection here . You can add it to template struct sensor via clever metaprogramming, it's very wide subject (and mind bending, sometimes).
names of all types you want to support have to be known in advance.
One possible variation is adding RTTI "framework hook" such as static const sensor<Myclass> rtti_MyClass; to implementation files where class names are already known and let the constructor do the work. They would also have to be complete types at this point to enable introspection in sensor.

How do I write a function that accepts arguments of different types with the same interface?

Consider this simplified example:
#include <list>
typedef std::list<int> IntList;
class KindaIntList {
public:
IntList::const_iterator begin() const { /* do some stuff */ }
IntList::const_iterator end() const { /* do some stuff */ }
// ...etc
};
The KindaIntList class implements some of the methods of the STL list.
Now, I have a function
void f(IntList l) {
// do stuff
}
which only calls methods that are implemented by KindaIntList. I would like to be able to call it with an IntList or with a KindaIntList argument. Is that possible?
I thought about using templates, but the definition of f is quite large and I don't want to put it in a header file (f is a member of a class, and I don't want it to be inlined).
Edit
The function f is actually a virtual member of another class; so I'm not sure how to make it into a template member.
Despite your misgivings about templates, this really is an appropriate spot to use C++ templates. Template functions perfectly capture the notion of "this function works with any arguments, as long as the operations I perform on those arguments are well-defined."
You don't need to worry about inlining in this case. Unless you define f inside of the body of a class, it won't automatically be inlined, even if it's a template. For example, in this code:
class MyClass {
public:
template <typename T> void f(T&);
};
template <typename T> void MyClass::f(T&) {
/* ... implementation ... */
}
Because f isn't defined inside of the MyClass body, it's not considered an inline function.
As for your concern about making the header file too large, I contend that this really isn't something to worry about. If you're worried about making the header too large, you can either put a big comment about halfway down saying something like
/* * * * * Implementation Below This Point * * * * */
Alternatively, you could make a separate .h file for the template implementation, then #include that file at the bottom of the header file. This shields the client from seeing the template implementations unless they actively go looking for it.
Hope this helps!
EDIT: If f is virtual, then you cannot make it a template function (as you've probably figured out). Consequently, if you want to make it work for "things that happen to look like std::list," then you don't have many good options. Normally you'd create a base class for both std::list and your custom list type, but this isn't an option as you can't modify std::list.
Fortunately, there is a way to treat std::list and things that look like it polymorphically using a trick called external polymorphism. The idea is that while you can't make the appropriate classes behave polymorphically, you can add an extra layer of indirection around those objects by introducing a polymorphic class hierarchy that just forwards all its requests to the objects that themselves are not polymorphic.
If you're willing to pull out the Big Template Guns, you can encapsulate this logic inside of a class that works much the same way as the new std::function template type. The idea is as follows. First, we'll create a polymorphic base class that exports all the functions you want to call as pure virtual functions:
class List {
public:
virtual ~List() {}
virtual std::list<int>::const_iterator begin() const = 0;
virtual std::list<int>::const_iterator end() const = 0;
virtual void push_back(int value) = 0;
/* ... etc. ... */
};
Now, we can define a template subclass of List that implements all of the public interface by forwarding all of the calls to an object of the actual type. For example:
template <typename T> class ListImpl: public List {
private:
T& mImpl; // Actual object that does the work
public:
/* Constructor stores a reference to the object that actually does the work. */
ListImpl(T& impl) : mImpl(impl) {
// Handled in initializer list
}
/* These functions all forward the requests to the implementation object. */
virtual std::list<int>::const_iterator begin() const {
return mImpl.begin();
}
virtual std::list<int>::const_iterator end() const {
return mImpl.end();
}
virtual void push_back(int value) {
mImpl.push_back(value);
}
/* ... etc. ... */
};
Now that you have this wrapper, you can implement f so that it takes in a List:
class MyClass {
public:
void f(List* myList) {
myList->push_back(137); // For example
}
};
And you can call this function on an object that looks like a list by first wrapping it in an object of type ListImpl. For exmaple:
MyClass mc;
std::list<int> myList;
MyIntList myIntList;
mc->f(new ListImpl<std::list<int> >(myList));
mc->f(new ListImpl<MyIntList>(myIntList));
Of course, this is bulky and unwieldy. You also have to worry about resource leaks, which aren't very fun. Fortunately, you can solve this by wrapping up all the logic to deal with List and ListImpl in a helper class, like this one here:
class ListWrapper {
public:
template <typename ListType> ListWrapper(ListType& list) {
/* Store a wrapper of the appropriate type. */
mImpl = new ListImpl<ListType>(list);
}
/* Delete the associated implementation object. */
~ListWrapper() {
delete mImpl;
}
/* For each interface function, provide our own wrapper to forward the logic
* to the real implementation object.
*/
std::list<int>::const_iterator begin() const {
return mImpl->begin();
}
std::list<int>::const_iterator end() const {
return mImpl->end();
}
void push_back(int value) {
mImpl->push_back(value);
}
/* ... etc. ... */
/* Copy functions necessary to avoid serious memory issues. */
ListWrapper(const ListWrapper& rhs) {
mImpl = rhs.mImpl->clone();
}
ListWrapper& operator= (const ListWrapper& rhs) {
if (this != &rhs) {
delete mImpl;
mImpl = rhs.mImpl->clone();
}
return *this;
}
private:
List* mImpl; // Pointer to polymorphic wrapper
};
You can now write f to take in a ListWrapper like this:
class MyClass {
public:
virtual void f(ListWrapper list) {
list.push_back(137); // For example
}
};
(This assumes that you've updated List and ListImpl with a virtual clone function that makes a copy of the object, which I've omitted for brevity's sake).
And magically, this code is now legal (and safe!):
MyClass mc;
std::list<int> myList;
MyIntList myIntList;
mc.f(myList);
mc.f(myIntList);
This code works because the template constructor for ListWrapper will automatically infer the type of its argument and implicitly create an object of type ListImpl appropriate for that object. It also encapsulates the memory management for you, so you never see any explicit news or deletes. Moreover, it means that you can pass in any object that you'd like and everything will work automatically - we've essentially made anything that looks like a list polymorphic by using a parallel class hierarchy!
Whew! That was fun! Hope this helps!
You could overload f to either take IntList and KindaIntList like this:
void f(IntList l){...}
void f(KindaIntList l){...}
Or make it take iterators:
void f(IntList::iterator first, IntList::iterator last){...}
That said, templates are really the best choice here, for both cases:
template<class ListT>
void f(ListT l){...}
template<class Iter>
void f(Iter first, Iter last){...}

Passing objects of different types with the same interface

I have a number of class, all with exactly the same interface. This interface defines a few methods, some of which are templated (the class itself may or may not be).
So the interface looks something like this
class MyClass
{
public:
void Func1();
template <typename T>
void Func2(T param);
};
I have a number of functions which take various objects which conform to this interface but want to avoid having to know the exact implementation at compile time.
Obviously, the default C++ solution would be to have a base type that all these classes derive from and pass around a pointer to that and have polymorphism do all the work.
The problem is that templated member functions cannot be virtual so this method cannot be used. I also want to avoid changing the current set of classes that follow this interface because there are a large number of them, some of which are defined outside the scope of my project.
The other solution is to template the functions that use these objects so they specialise for the right type. This could be a solution but due to legacy requirements templating a large number functions may not be possible (this is something I cannot do anything about as the client code isn't something I have responsibility for).
My initial thought was to provide some kind of carrier class which is type neutral and in effects wraps the common interface here and has a base interface class to pass around the internal type.
Something along the lines of
class MyInterface
{
public:
virtual void Func1() = 0;
};
template <typename T>
class MyImplementation
{
public:
virtual void Func1()
{
m_impl->Func1();
}
private:
T* m_impl;
};
But again the templated member functions seem to block this approach.
I looked at the boost::any and boost::function classes which I thought might offer some kind of solution but they don't seem to give me the right answer.
So, does anyone have any suggestions or work around on how to make this possible, if indeed it is? Personally I'm leaning towards having to template the various functions that require these objects - since that's the functionality templates provide - but thought it worth investigating first.
Thanks in advance
What's not entirely clear to me is how you're resolving the parameter T to Func2, do you need some kind of dynamic dispatch on that too, or is it known at compile time at the call site?
In the former case, it sounds like multimethods. In the latter, how about this variation on your interface idea:
#include <iostream>
template<class T> struct generic_delegate
{
virtual void call(T param) = 0;
};
template<class U, class T> class fn_delegate : public generic_delegate<T>
{
U* obj;
void (U::*fn)(T);
public:
fn_delegate(U* o, void (U::*f)(T)) :
obj(o), fn(f)
{}
virtual void call(T param)
{
(obj->*fn)(param);
}
};
class A
{
public:
template<class T> void fn(T param)
{
std::cout << "A: " << param << std::endl;
}
};
class B
{
public:
template<class T> void fn(T param)
{
std::cout << "B: " << param << std::endl;
}
};
template<class T, class U> generic_delegate<T>* fn_deleg(U* o)
{
return new fn_delegate<U, T>(o, &U::template fn<T>);
}
int main()
{
A a;
B b;
generic_delegate<int>* i = fn_deleg<int>(&a);
generic_delegate<int>* j = fn_deleg<int>(&b);
i->call(4);
j->call(5);
}
Obviously, the thing you'd be passing around are the generic delegate pointers.
If you use templates you need to know AT COMPILE TIME which type(s) you're using. That's just the nature of templates (templates look like code that's dynamic at runtime, but in reality it's just shorthand that tells the compiler what versions of the function to compile and include in the object code). Best case senario is something like this:
template <class T>
void DoSomethingWithMyInterface(MyInterface<T> X)
{
//do something
}
...
switch (MyObject.GetTypeCode())
{
case TYPE1: DoSomethingWithMyInterface<type1>(MyObject); break;
case TYPE2: DoSomethingWithMyInterface<type2>(MyObject); break;
case TYPE3: DoSomethingWithMyInterface<type3>(MyObject); break;
case TYPE4: DoSomethingWithMyInterface<type4>(MyObject); break;
}
I actually use this situation a lot. I write templated c++ code that does the processing for a dynamically typed language. That means that the top level language doesn't know the data types until run time, but I need to know them at compile time. So I create this "TypeSwitch" (I actually have a fancy reusable one). That looks at the datatypes at run time and then figures out which of the already compiled template functions to run.
Note - that this requires me knowing all the types I'm going to support before hand (and I do) and the switch statement actually causes the compiler to generate all of the code that could ever be executed. Then at runtime the right one is selected.