Search

Meta

14.3 — Template classes

In the previous two lessons, you learn how function templates and function template instances could be used to generalize functions to work with many different data types. While this is a great start down the road to generalized programming, it doesn’t solve all of our problems. Let’s take a look at an example of one such problem, and see what templates can do for us further.

Templates and container classes

In the lesson on container classes, you learned how to use composition to implement classes that contained multiple instances of other classes. As one example of such a container, we took a look at the IntArray class. Here is a simplified example of that class:

While this class provides an easy way to create arrays of integers, what if we want to create an array of doubles? Using traditional programming methods, we’d have to create an entirely new class! Here’s an example of DoubleArray, an array class used to hold doubles.

Although the code listings are lengthy, you’ll note the two classes are almost identical! In fact, the only substantive difference is the contained data type. As you likely have guessed, this is another area where templates can be put to good use to free us from having to create classes that are bound to one specific data type.

Creating template classes is works pretty much identically to creating template functions, so we’ll proceed by example. Here’s the IntArray classes, templatated version:

As you can see, this version is almost identical to the IntArray version, except we’ve added the template declaration, and changed the contained data type from int to T.

Note that we’ve also defined the GetLength() function outside of the class declaration. This isn’t necessary, but new programmers typically stumble when trying to do this for the first time due to the syntax, so an example is instructive. Each templated member function declared outside the class declaration needs its own template declaration. Also, note that the name of the templated array class is Array<T>, not Array -- Array would refer to a non-templated version of a class named Array.

Here’s a short example using the above templated array class:

This example prints the following:

11     11.5
10     10.5
9       9.5
8       8.5
7       7.5
6       6.5
5       5.5
4       4.5
3       3.5
2       2.5
1       1.5
0       0.5

Templated classes are instanced in the same way templated functions are -- the compile stencils a copy upon demand with the template parameter replaced by the actual data type the user needs and then compiles the copy. If you don’t ever use a template class, the compile won’t even compile it.

Template classes are ideal for implementing container classes, because it is highly desirable to have containers work across a wide variety of data types, and templates allow you to do so without duplicating code. Although the syntax is ugly, and the error messages can be cryptic, template classes are truly one of C++’s best and most useful features.

A note for users using older compilers

Some older compilers (eg. Visual Studio 6) have a bug where the definition of template class functions must be put in the same file as the template class is defined in. Thus, if the template class were defined in X.h, the function definitions would have to also go in X.h (not X.cpp). This issue should be fixed in most/all modern compilers.

14.4 -- Expression parameters and template specialization
Index
14.2 -- Function template instances

9 comments to 14.3 — Template classes

  • Vinitha Krishnamurthy

    Alex,

    I think, IntArray class uses composition and not aggregation. It is a value container class and not a reference container class.

    Vinitha

    [ I am constantly amazed by the attention to detail that my readers possess. Very nice catch, and I appreciate you bringing it to my attention. -Alex ]

  • Gilles

    T Array::GetLength() shall return an int instead of a T

    [ Fixed! Thanks. -Alex ]

  • Tobi

    should be

    ?

  • Pradeep

    Hi Alex,

    The template version you provied if instatiated by a ‘char’ it may cause problems becaue incounstructor you gave “new T[length] but for char it needs ‘new T[length+1]’ ( beacues of “”).

    So changing the consturctor to the following may be appropriate.

    Also we need to include
    typeid determine sthe data type at runtime.

    What do you say?

  • Sergey

    “Some older compilers (eg. Visual Studio 6) have a bug where the definition of template class functions must be put in the same file as the template class is defined in. Thus, if the template class were defined in X.h, the function definitions would have to also go in X.h (not X.cpp). This issue should be fixed in most/all modern compilers.”

    No.It is still not implemented in most of compilers and you have to use inclusion model. See discussions on Stackoverflow.com:Why should the implementation and the declaration of a template class be in the same header file?[^]

  • Sergey

    Actually, the program will most likely pass the compilation, but linker will report an error implying there is no function definition(s).

  • the compile(r) won’t even compile it.

  • Ville K

    So fix last for-loop!
    1. check decrementing of nCount: remove additional “-” characters and “;”-character at the end of loop-definition
    2. consider to use “\t” instead of “t” for printing tabs

Leave a Comment

  

  

  

8 − 1 =

Put C++ code inside [code][/code] tags to use the syntax highlighter