If you never write C++ templates before or you are not sure how to start with C++ template, then this tutorial is right for you. This tutorial will guide your on how to write your first template class in C++.

Let’s take a look of the following MyArray class that written in C++. The class called MyArray and it served as a container which allow user to store and retrieve data from the integer pointer array called m_Array.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class MyArray
{
public:
  MyArray(int size) : m_Size(size)
  {
    m_Array = new int[size];
  }

  ~MyArray(void)
  {
    if(m_Array != NULL)
    {
      delete[] m_Array;
      m_Array = NULL;
    }
  }

  int Count() const
  {
    return m_Size;
  }

  int& At(int index)
  {
    if (index < 0 || index >= Count())
      throw std::out_of_range ("index out of range.");

    return m_Array[index];
  }

protected:
  int m_Size;
  int* m_Array;
};

Some information about the class as following:

1. The constructor allow user to set the size of the m_Array pointer array.
2. The destructor will free the m_Array pointer array.
3. The count function will return the depth or the size of m_Array pointer array.
4. The At function, which is a reference type, will allow user to retrieve or set data value to m_Array pointer array at the specified index.

Well, that’s all of the class and here is how it look like in the main function in order to utilize the class. Compile the following code and you should see the following output.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int _tmain(int argc, _TCHAR* argv[])
{
  // Create a int array with size of 5
  MyArray intArray(5);

  // Get the array size
  std::cout <<  "Array size: " << intArray.Count() <<  std::endl;
 
  // Set value at index
  intArray.At(0) = 100;
  intArray.At(1) = 200;

  // Get value at index
  std::cout <<  "intArray[0]: " << intArray.At(0) <<  std::endl;
  std::cout <<  "intArray[1]: " << intArray.At(1) <<  std::endl;

  getchar();
  return 0;
}
C++ Template Example

The code look ok as far as we are dealing with integer data type. However, if we would like to add additional support for new data type, e.g float, daouble, string, etc, then we can copy/paste the same class and change its data type accordingly. Wait a minute, is this the right ways to code in C++ ? By doing so, we don’t RE-USE our code at all. In fact, We are creating duplicated code.

To solve the problem, we can utilize the C++ template. This allows us to create a template class whose functionality can be operated with generic types. We don’t have to repeat the entire code for each data type we wish to support.

Let’s modify MyArray class in order to support C++ template.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
template<typename T>
class MyArray
{
public:
  MyArray(int size) : m_Size(size)
  {
    m_Array = new T[size];
  }

  ~MyArray(void)
  {
    if(m_Array != NULL)
    {
      delete[] m_Array;
      m_Array = NULL;
    }
  }

  int Count() const
  {
    return m_Size;
  }

  T& At(int index)
  {
    if (index < 0 || index >= Count())
      throw std::out_of_range ("index out of range.");

    return m_Array[index];
  }

protected:
  int m_Size;
  T* m_Array;
};

The template at the beginning of the class telling that this is a template class that accept only one data type, T. Well, you can use any name you want except that it’s not a reserved keyword. Remember that T is generic type and it can be refers as any data type.

m_Array will no longer be int type. It need to be T type in order to become a generic type. Also, in the constructor, m_Array will be initialize as T type instead of int.

Well, that’s all we need to change and here is how it look like in the main function in order to utilize the class. We are creating 3 different data type by using the same template class. Compile the following code and you should see the following output.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
int _tmain(int argc, _TCHAR* argv[])
{
  // Create an int array with size of 5
  MyArray<int> intArray(5);
 
  // Get intArray  size
  std::cout <<  "intArray size: " << intArray.Count() <<  std::endl;
 
  // Set int value at index
  intArray.At(0) = 100;
  intArray.At(1) = 200;

  // Get int value at index
  std::cout <<  "intArray[0]: " << intArray.At(0) <<  std::endl;
  std::cout <<  "intArray[1]: " << intArray.At(1) <<  std::endl << std::endl;

  // Create a bool array with size of 5
  MyArray<bool> boolArray(5);

  // Get boolArray size
  std::cout <<  "boolArray size: " << boolArray.Count() <<  std::endl;
 
  // Set bool value at index
  boolArray.At(0) = true;
  boolArray.At(1) = false;

  // Get int value at index
  std::cout <<  "boolArray[0]: " << (boolArray.At(0) ? "true" : "false") <<  std::endl;
  std::cout <<  "boolArray[1]: " << (boolArray.At(1) ? "true" : "false") <<  std::endl << std::endl;

  // Create a string array with size of 5
  MyArray<std::string> strArray(5);

  // Get boolArray size
  std::cout <<  "strArray size: " << strArray.Count() <<  std::endl;

  // Set string value at index
  strArray.At(0) = "Hello";
  strArray.At(1) = "World";

  // Get int value at index
  std::cout <<  "strArray[0]: " << strArray.At(0) <<  std::endl;
  std::cout <<  "strArray[1]: " << strArray.At(1) <<  std::endl;
 
  getchar();
  return 0;
}
C++ Template Example

Download source code: TemplateSample.zip