Hello everyone, the concept of generic programming or meta programming is becoming popular nowadays. C++ is one of the most favorite languages used by many programmers all over the world. Generic programming is a very powerful feature supported by C++ but unfortunately, while studying this language most of the time this topic remains untouched by many learners. I would like to give a brief introduction to this topic and make you familiar with generic programming in C++. So, without wasting time on more words I would directly like to jump on the topic by introducing you all to what is meant by generic programming.
“Writing code that works with a variety of types as arguments, as long as those argument types meet specific syntactic and semantic requirements.’’
— Bjarne Stroustrup
In simple words, we can say that whenever we write some code or function in such a way, it works on almost any data type that is nothing but generic programming.
The template in C++ is a feature that allows us to define generic functions and classes which ultimately leads to having support for generic programming in C++.
What is C++ Template
A template is a generic blueprint that the compiler uses to generate specialized functions and classes. We define a template with the placeholder type and then we plug in the actual type we want when we need it. Then the compiler generates the specific class that we need. Always remember that all this stuff happens only at compile time in C++. If you know other programming languages, you might have seen this happening at run time. This gives an advantage in a way that compiler checks the types at compile time by itself before executing the program which reduces the risk of run time error. The main idea behind this is we just need to define the blueprint of a function or class and the compiler will generate the actual code for it later by deducing its type.
C++ basically supports Function and Class template.
In this section, we will see how to create a template function. Suppose we have a function called max, which returns the maximum of two numbers passed to it. If we created such a function normally in our C++ program for int data type, then it would look like as shown above.
But what if we want to pass a double value or char value to this function? If we do so we will get a compile-time error. Because the type for which we created that function is int. So, to create the same function for any other data type, we need to again write the same code by just changing the return type of function and the type of argument. Besides that, everything in the function body will be redundant. This problem can be solved with the help of generic programming using the Function template.
To declare a function template, we have the following syntax.
Let us walk through the above syntax. First, we have a template keyword that indicates that this function is a template function. Next is the class which is a keyword that specifies the generic type in the declaration of template. We can also write alternative keywords as typename instead of class. Ttype is the placeholder for the data type of our function. It is also used inside the body of a function. The compiler automatically replaces the Type with the actual data type. So, the template for our max function would look as shown below.
As you can see in the above image T is the Ttype which we called a placeholder for our data type and you can use any letter there instead of T.
Now, we can use this function for any type of data that supports the > (greater than) operator. For example, we can now pass a string, char, int, double any kind of data to our function, and code for it remains the same.
To call the above max function we use the syntax as
In the above code, you can see that we have called max function in two ways.
First by having our datatype specified in <> brackets as int. The compiler will replace this datatype with the T that we specified as a placeholder while defining our template function. But if we do not specify the type and directly pass the arguments then the C++ compiler will automatically deduce the type of data that we passed to it as an argument.
Similarly, we can use the same function for other data types as shown below.
I think now it is quite clear that how you can declare a dynamic template function in C++ that can work on different data types for performing the same functionality.
One thing to note here is we cannot use this template function directly with user-defined data types such as a structure. Suppose if we have a structure named as a stud. It contains two members stud_id and stud_name. If we pass this data type to our max function it would not work because operator > (greater than) must be overloaded for this case. Hence in such cases, we need to define our own compare logic by overloading > (greater than) operator.
As of now, we saw what a function template means and how we implement it. Now let us look at the class template. The class template is similar to the function template but instead of creating a generic function we will be creating a generic class and that implies all attributes, methods, constructors, and destructors of a class. Just as we can plug in any data type to a function, we can do the same to a generic class. In the previous section, we wrote a blueprint for a function. Now in this section, we will be writing the blueprint for a class. The compiler then generates the appropriate class from the blueprint. If you are already familiar with the STL library of C++, you must be knowing about vectors. When we create vectors, we specify the type of data we want to store in our vector. So, we can say that it is also a blueprint of a generic class. That is what metaprogramming is all about.
Suppose you want to store different types of data together as a node, so we have a class named as
Node as shown below,
In the above code snippet, we have created a class Node with two private members of type int and string and we have setters and getters for both the attributes. I hope everyone is familiar with the OOPS concepts. Now imagine if I want that class to store data of type double instead of int. The most straightforward option that we have is to create a new class with another name and define the required type of data and write some code for it. So, to solve this issue we have a template class.
Let us learn to create a class template in C++.
In the above syntax first, we have template keywords with <> brackets. It indicates that the below class is a template class. Next in the arrow brackets, we have typename which is a keyword that specifies the generic type in the declaration of a template class. Previously we used class keywords as I told typename and class both works and are used for the same purpose. Type is the placeholder’s name. It is determined when the class is instantiated. If we want to define more than one generic type, we can use the comma between the two types. Next, we use Ttype to use as a data type placeholder for our attributes and methods as well. As I already mentioned we can use more than one type s if we have different attributes of different types, we can specify a unique letter for them. You will understand it with an example.
In the above example, we have declared a template class named Node which has T as a placeholder for a specific data type which will be determined by the compiler when we instantiate the object of that class. We have specified two attributes there named as first and second. Both have the same type as T (Placeholder). Also, getter methods would also have the same return type as attributes.
If we use multiple data types in our template class so that different attributes could have their different types. As in the previous case, we had an int and string. So, we can make changes in our template accordingly,
In the above code snippet, we have taken two Types named T1 and T2. There are two attributes in our class named first and second. The first attribute is declared as of type T1 and the second is declared of type T2. Similarly, both attributes have their setter and getter methods with the corresponding typename as their return type. Also, you can see that the argument that is passed to setter methods is also defined as typename T1 and T2, respectively. This concludes that we can use typename within the body of the class wherever it is required.
Now as we have learned how to define a template, or a generic blueprint of a class let us see how we instantiate this class.
So, as usual, it is very simple, we have the className as the name of our class and objectName is the name of our object. The type in the <> brackets is the type for which we want to create our generic class. If we have defined multiple typename in the blueprint, then it mandatory to pass it while instantiating by separating with a comma.
In the above example, as you can see, we have created an object of the class Node as n1. Our Node class has two typename T1 and T2 which will be now replaced with string and double, respectively. As we had declared the first attribute of type T1 it will be now a string so for the setter method we have passed a string “abcd” and for the getter method, we stored the result in a string variable first. Similarly, we did that for our second attribute.
Now I guess you must be quite clear about generic programming in C++. Also, you are now familiar with functional and class templates in C++. All the containers in C++ STL such as vectors, pairs, maps all are implemented using a generic class template. That is why we have the same syntax for instantiating STL containers of C++. This gives them the dynamic nature of types which makes our programming more flexible and efficient. Above is a small recap of what we studied in this blog.
1. C++ supports Generic programming with the help of powerful features called templates.
2. Templates are of two types of Function and Class and they allow us to create function and classes which can support different data types.
3. This results in faster and efficient development and reduces the redundant code in our project.
4. Functions and class templates support multiple parameters with different types.
Generic programming - Wikipedia
Generic programming is a style of computer programming in which algorithms are written in terms of types…
C++ Templates - javatpoint
A C++ template is a powerful feature added to C++. It allows you to define the generic classes and generic functions…
Authors: Tanay Vartak, Shailesh Kadam, Tasmiya Kankurti, Rutvik Deshmukh, Kalyani Vidhate.