2

I'm coming from C, and getting deeper and deeper into C++. Using the container classes of the standard library, as-well as the smart pointer classes from the boost library, I've had my first introduction to class templates. I use them a lot now.

Recently I made my first approach of writing my own class templates. But 99% of what I can think of, where a class template might be useful, the class template already exists in the standard library or one of the boost libraries.

When do you decide to implement something as a class template? What is your criteria? Do you have an example?

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
AudioDroid
  • 2,292
  • 2
  • 20
  • 31
  • 4
    IMHO I find it very good practice to re-implement stuff that already exists! –  Dec 01 '10 at 14:37
  • @Muggen Indeed. In my opinion, it's bad to use something when you don't know how it works. – Maxpm Dec 01 '10 at 14:46
  • @Muggen, @Maxpm: I agree that it is a good idea to try to re-implement "stuff that already exists" to understand how it works and for practise. I will do that. But my question is when do you write templates in "reality", not for practise? – AudioDroid Dec 01 '10 at 15:09

9 Answers9

4

C++ proposes several programming paradigms, as you have discovered, and they are not exclusive.

What you write with templates could generally be written with Object-Oriented codes, so it's usually a matter of trade-off.

The C++ templates follow the Generic Programming paradigm, the idea is that your class / method will be able to work with any type, as long as the instances of this type follow a Concept.

The first striking difference, with regard to Object-Oriented code, is that there is no need for a common base class. In fact, combining templates and free-functions, you can effectively work with an heterogeneous set of objects.

That is therefore when they shine:

  • If you have an heterogeneous set of objects with which you want to work
  • If refactoring them is not possible (for various reasons)

then using a template seems a very good idea.

Generally speaking, I've mainly created them either for small utilities or for frameworks. In "business" code I use them, but I rarely define new ones. For example:

  • box::Enum<typename EnumType> which wraps an enum an proposes seamless conversion to/from string (useful for pretty printing in the logs), serialization and the like
  • box::Identifier<typename T> which wraps an integer (essentially) and allow me to create a hierarchy of identifiers types similar to the hierarchy of types, so that a DummyObjectId can be passed when one would expect an ObjectId, but not the other way around

In general, there are therefore two situations in which I used templates:

  • preventing copy/pasting
  • increasing type safety

If you find yourself in one of those, perhaps could you think about it.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • Thanks, this is the kind of answer I was hoping for. :-) – AudioDroid Dec 01 '10 at 16:00
  • Can you elaborate a bit more on the EnumType wrapper? Or post a link...? That would be great. – AudioDroid Dec 08 '10 at 11:57
  • @AudioDroid: I don't have a link, but the idea is simple. You provide a template class that will be templated over a struct in which the enum will be defined (for scoping), a local static vector is provided containing the list of enum, associated to their string representation (generated by a single macro), and an instantiation of the class is simply an iterator over the vector (allowing an implicit "invalid" state for the non-initialized form). You are then free to define your methods (`<`, `++`, `==`, `<<`, ...) as you wish. – Matthieu M. Dec 08 '10 at 13:55
  • Doesn't sound simple to me, but sounds slick and useful. I will try it sometime (hopefully soon) and see how far I get. – AudioDroid Dec 09 '10 at 11:44
2

The first example I can think about is image processing. Let's say that you need to implement some algorithm which can be applied to images with different pixel types: unsigned char, unsigned short, unsigned int, float. This should be done using templates.

Alex F
  • 42,307
  • 41
  • 144
  • 212
  • Okay. This sounds interesting/understandable. But...how do you decided to go for a generic, and not work with inheritance (e.g. interface/abstract class/etc.)? – AudioDroid Dec 01 '10 at 15:11
  • This is the same algotithm, applied to different data types. Typical case for generics. The same behavior, different types. – Alex F Dec 01 '10 at 16:15
  • 1
    Inheritance implements different behavior. Another criterion for inheritance: decision about specific implementation is done at runtime, and for templates - at compile time. – Alex F Dec 01 '10 at 16:17
  • run-time/compile-time is the key, suggest you edit your answer accordingly. – Jason S Dec 01 '10 at 19:00
  • you are wrong... of course you can decide which specific implementation at runtime for templates aswell, but that will require additional code, like e.g. a switch-case which picks the correct processing function for a specific image format*. Similar with both approaches is, that you will have to know at compile time, what kind of specific implementations you might need at runtime. (*: if the same decision is necessary more than once, you can use function pointers, so you will have to make the decision only once) – smerlin Dec 01 '10 at 21:50
2

When it didn't exist in the standard library or boost.

There is no point in reimplementing something that already exists.

If you want some cool examples of how templates can be used in software design, read this book: Modern C++ Design

Šimon Tóth
  • 35,456
  • 20
  • 106
  • 151
  • Okay. [Moo-Juice] answer points out the policy-based design. Following the link to Wikipedia, I can read that this design was first popularized in the book "Modern C++ Design", that you are pointing out here. Thanks. – AudioDroid Dec 01 '10 at 15:16
  • 2
    @Audio Actually the book contains more things then just the Policy based design. It's a good read, I highly recommend it. – Šimon Tóth Dec 01 '10 at 15:21
  • +1, there's much more to the book than that! – Moo-Juice Dec 01 '10 at 15:23
2

The criteria of when I am going to use a template (or not) really depends on what I am doing. They come in to play a lot when using policy-based design ( http://en.wikipedia.org/wiki/Policy-based_design ).

Moo-Juice
  • 38,257
  • 10
  • 78
  • 128
1

You implement something as a class template according to two criteria:

  1. Include dependencies. Too many includes can slow compilation, and having to order them and suchlike is a real mess. Don't make a new class template if you can't stand crapping around with include, definition and declaration orders for hours on end.
  2. Implementation dependencies. If you don't require a type to be specific for an implementation, then you should allow for it to be templated. The easiest example is an array- it behaves the same whatever type it's of. This increases maintainability.

Oh, and if it doesn't already exist in STL/Boost. It is the job of those libraries basically to be all the commonly useful templates, you know.

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
Puppy
  • 144,682
  • 38
  • 256
  • 465
1

I rarely write templates. I use them a lot - STL, Boost, etc - but that's consumption not production.

There are a few exceptions:

  • Rare functions that the STL left out, such as copy_if
  • An intrusive smart pointer (Boost wasn't good enough back then)
  • Helper functions when I didn't want to spell out a type (Template Argument Deduction as a cheap decltype replacement)

So, with C++0x coming I expect to write even less templates.

Community
  • 1
  • 1
MSalters
  • 173,980
  • 10
  • 155
  • 350
0

In most cases, you need templates only when you are writing somthing generic, but not existing yet in boost/stl. This is really rare situation, I've never written templates in production software.

BarsMonster
  • 6,483
  • 2
  • 34
  • 47
0

I'll apply my favourite answer, use a little common sense! Templates aren't exclusively in the domain of containers and algorithms on them; I use them extensively for example, to allow me to use composition rather than inheritance - in production code ;) ...

Nim
  • 33,299
  • 2
  • 62
  • 101
0

Templates are another form of re-usable code. So I use the same criteria as for functions, classes, etc. My rule of thumb (which I heard somewhere, but cannot find a reference right now,) is that reusable code is 3 times as expensive to write, so you need to use it at least 3 times to come out even. If you do not have 3 cases, then you are better off writing two copies. Yes, I know, sacrilege....

There are obvious exceptions, for example, if I am writing a function / class that will be trivial to make generic, I would make it so even for 2 uses. I would not for just one use. The extra complexity is going to trip somebody reading the code in the future.

coryan
  • 1,183
  • 8
  • 6