When, why, and how to use templates in C++?

Started by
11 comments, last by DevLiquidKnight 20 years, 4 months ago
I was wondering if I could find out why one would need to use templates, what exactly they could enable me vs what they cant enable me to do. And exactly where I can find a good site about using them in the C++ syntax. I''ve read the SDK about them, however I wish to expand on that any good sites/info that anyone could suggest would be great . coder requires 0xf00d before continue().
Killer Eagle Software
Advertisement
http://www.gamedev.net/community/forums/topic.asp?topic_id=195657


Check my post on that one (the first one I posted, there are 2). It has a bit of template stuff there, and is very usefull to me .

Basically, templates allow you to write a function once and use it for multiple types... for example, a swap function that can accept any type!

template
void Swap(T &v1, T &v2)
{
T tmp1;
tmp = v1;
v1 = v2;
v2 = tmp;
}

This way, you don''t have to write it specifically for each and every type! The example in my other post uses a templated class for a linked list, so I can store a linked list of any type without having to write it multiple times!
I found this and this .

Basically anytime when a certain class may need different data types.

For example, I template my vertex stuff, so I can have a

Vector3f (3 part vector with floats)

or a Vector4i (4 part vector with integers)

or a Vector2l (2 part vector with longs)
TechleadEnilno, the Ultima 2 projectwww.dr-code.org/enilno
As for the ''when'' of using templates: templates should be used when they''re the most appropriate way to represent what you''re trying to do. Once you understand what templates can and can''t do, it''ll be easier to decide when to use them.

Consider std::complex. This class is templated—usable with floats, doubles and long doubles. The programmer can choose the appropriate precision for any given program, and std::complex only needed to be written once to achieve this.
I kinda know about some stuff im just basically trying to extend my object orientated knoweldge to the limit

coder requires 0xf00d before continue().

Killer Eagle Software
All of the examples previous posters gave are just trivial uses of templates. There is a whole lot more to them than that and you just have to start looking through template-based libraries like Boost and Loki. You have to know your C++ cold to be able to make sense of those though. Andrei Alecsandru''s "Modern C++ Design" is the penultimate guide on using templates (he authored Loki).

Templates aren''t object-oriented, they are a different paradigm called generative programming that C++ just happens to support well.
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis
One of the most interesting uses of templates is meta programming - by using specialisation it is possible to evaluate stuff at compile time, for example this is a very neat (although trivial) example:
template<int n> struct factorial {    const static int eval = n * factorial<n-1>;};// specialisation of the template to catch the case that n=0, means the compiler stops evaluating at this pointtemplate<> struct factorial<0> {    const static int eval = 1;};// Somewhere in your code...void somefunc() {    int z = factorial<5>::eval;    cout << "factorial 5 = " << z << endl;}


NB: for this code to work you need a highly compiliant compiler! Visual Studio.NET 2003 is fine with this (I suspect gcc too ??, no idea about other compilers though).

As I said before this is a really trivial example, but it is very neat b/c the factorial is evaluated at compile time (obviously it won''t work with variables) so there is no associated runtime cost! you could obviously use this more usefully, for example the factorial example would be useful in a Taylor (sp?) expansion.

One library which makes excellent use of this is "blitz++" (its raison de etre is metaprogramming via the template mechanism to help the optimiser).
I use templates to simplify things.

For instance, I usually do dynamic linking of the dlls I make. Instead of writing code for every function pointer of the functions in my dlls, I just do it generically with
template<typename T> void LoadFunction(const char *const functionname, T *funcptr){	*funcptr = (T)GetProcAddress(DLL, functionname);}


Usage:

CREATESOUNDSYSTEM pfnCreateSoundSystem = 0;HINSTANCE DLL = LoadLibrary("MyDll.dll");LoadFunction<CREATESOUNDSYSTEM>("CreateSoundSystem", &pfnCreateSoundSystem);


Works like a charm .

Templates work very nice when you don't want to write similar code for every data type you think you'll use



[edited by - Maega on December 13, 2003 9:38:18 PM]
quote:Original post by Maega
I use templates to simplify things.

...
CREATESOUNDSYSTEM pfnCreateSoundSystem = 0;

HINSTANCE DLL = LoadLibrary("MyDll.dll");

LoadFunction<CREATESOUNDSYSTEM>("CreateSoundSystem", &pfnCreateSoundSystem);
You could save a little more typing, since, here, the compiler can figure out what type the template needs. You only need:

LoadFunction("CreateSoundSystem", &pfnCreateSoundSystem);
Yeah its sad that C++ classes won''t deduce template parameters. I hate having to write:
std::auto_ptr dll(new DLL(L"Core.dll")); 

When anyone can figure out what type I need. However, it is trivial to come up with situations where it can''t always know quite as well, so I guess they err on the conservative side as always.
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis

This topic is closed to new replies.

Advertisement