Language Selector

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 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 compiler 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 compiler 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
14.2 -- Function template instances

23 comments to 14.3 — Template classes

  • Vinitha Krishnamurthy


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


    [ 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 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

  • Gopal

    I have a question but not related to Template.

    A generic question. What i think is that there might be a lots of library available to ready made use of codes. Like the example code you have given for data holding array, for sorting, for minmax, for searching etc. Am i right?

    How do i know which are codes ready made available for use for these type of different tasks?

    These codes might sit in different types of libraries. But i am not sure. If it is so, i have to dig out libraries for these codes for what i want to achieve? Correct?

    • Alex

      If I’m understanding you correctly, you’re asking whether there are existing libraries that you can use to help write programs? If so, the answer is YES! The C++ standard library is the main one, and it has a ton of useful functionality in it. Beyond that, third-party libraries, such as Boost, SDL, and QT provide additional useful functionality that you can leverage. The internet is full of documentation on what’s in these libraries (once you know the name of them, so you can look them up).

  • Reaversword

    Is it possible to have a more-than-one templated type in a function?

    Something like this:

    This actually doesn’t works, but I hope the idea shows clear.

    • Reaversword

      Ok, I found the way, just replace the two template definitions with:

      template <typename T, typename S>

      (and add a ";" to "return y-x", I forgot that!).

      Sorry Alex, I’m putting you homework with my comments. I’ll try to ask, as usual, and public the answer if I find it.

  • Lokesh

    "Templated classes are instanced in the same way templated functions are -- the compile stencils" --> compiler
    Same paragraph - “, the compile won’t even compile it.” --> compiler

  • Gocha

    Found a typo.

    You wrote: "Creating template classes is works pretty much identically to creating template functions"

    Should be: "Creating template classes works pretty much identically to creating template functions"

  • Graham L. Tasker

    Gioven the following simplified example :

    which fails to compile, how do you decalre a friend operator function for a templated class? I have tried other possible combinations, i.e. declareing the friend function as templated.

    • Alex

      Your operator== function needs to be declared as:

  • Graham L. Tasker

    Sorry about the typing error line 33 should read

  • Graham L. Tasker

    I have done what you suggested and obtain the following compiler errors:

    what do you suggest next?

  • Patrick Roncagliolo

    Hi Alex, I suggest you to update the last section with these useful informations:
    due to the compiler workflow, on most compilers template classes can’t be compiled in a ".h + .cpp" standard way. In fact, the compiler can’t know for which types it has to generate the appropriate classes from the template. Although this could be achieved with some tuning on compilers (such as looking forward the type that will be used during instantiation of a class template in other sources that are compiled together with the template itself), think about a way to compile and link successfully template classes in a project if they were collected in an already-compiled library… it’s considered very hard, (almost impossible in the standard way)! In fact the compiler hasn’t the sources of the template, and so it can’t instantiate the class properly. The prototype doesn’t suffice the needs of the compiler. Even the STL has the implementation code exposed in the headers or directly visible and available to the compiler, due to this reason. I’ll give you some links:
    Here you can find a workaround, that consist in explicitly telling the compiler to generate a class for pre-determined types (but the template will work only with tat limited subset of types instead of all types).

Leave a Comment

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




5 × 1 =