How to decide when to implement a C++ template? [closed]
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this questionI'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?
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 likebox::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 aDummyObjectId
can be passed when one would expect anObjectId
, 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.
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.
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
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 ).
You implement something as a class template according to two criteria:
- 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.
- 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.
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.
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.
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 ;) ...
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.
精彩评论