C++ Templates

Templates are the foundation of generic programming, a programming style that allows writing functions, classes, algorithms, and different code snippets that work with different data types.

A template is a blueprint or formula for creating a generic class or a function. The library containers like iterators and algorithms are examples of generic programming and have been developed using template concepts.

There is a single definition of each container, such as vector, but we can define many different kinds of vectors, for example, vector <int> or vector <string>.The two keywords that are used to define a template are template and typename.

Function Template

Function templates define a blueprint for functions that enables a function to operate on different data types without rewriting the same logic.

Syntax

The syntax for the general form of a template function definition is shown here −

template<typenameidentifier> function_declaration;

Here the ‘template’ keyword declares the generic function and ‘typename’ keyword specifies the type to be used for the parameter.

Example

Here is the following example of a function template that returns the maximum of two values.

#include <iostream>#include <string>usingnamespace std;template<typenameT>inline T const&Max(T const& a, T const& b){return a < b ? b:a;}intmain(){int i =39;int j =20;
   cout <<"Max(i, j): "<<Max(i, j)<< endl;double f1 =13.5;double f2 =20.7; 
   cout <<"Max(f1, f2): "<<Max(f1, f2)<< endl; 

   string s1 ="Hello"; 
   string s2 ="World"; 
   cout <<"Max(s1, s2): "<<Max(s1, s2)<< endl;return0;}

Output

Max(i, j): 39
Max(f1, f2): 20.7
Max(s1, s2): World

Class Template

Similarly, class templates also define a blueprint for creating classes that can work with any data type.

Syntax

template<classtype>classclass-name {...}

Here, type is the placeholder type name, which will be specified when a class is instantiated. You can define more than one generic data type by using a comma-separated list.

Example

Following is the example of defining class Stack<> and implementing generic methods to push and pop the elements from the stack −

#include <iostream>#include <vector>#include <cstdlib>#include <string>#include <stdexcept>usingnamespace std;template<classT>classStack{private: 
      vector<T> elems;// elements public:voidpush(T const&);// push element voidpop();// pop element 
      T top()const;// return top element boolempty()const{// return true if empty.return elems.empty();}};template<classT>voidStack<T>::push(T const& elem){// append copy of passed element 
   elems.push_back(elem);}template<classT>voidStack<T>::pop(){if(elems.empty()){throwout_of_range("Stack<>::pop(): empty stack");}// remove last element 
   elems.pop_back();}template<classT>
T Stack<T>::top()const{if(elems.empty()){throwout_of_range("Stack<>::top(): empty stack");}// return copy of last element return elems.back();}intmain(){try{
      Stack<int>         intStack;// stack of ints 
      Stack<string> stringStack;// stack of strings // manipulate int stack 
      intStack.push(7); 
      cout << intStack.top()<<endl;// manipulate string stack 
      stringStack.push("hello"); 
      cout << stringStack.top()<< std::endl; 
      stringStack.pop(); 
      stringStack.pop();}catch(exception const& ex){ 
      cerr <<"Exception: "<< ex.what()<<endl;return-1;}}

Output

7
hello
Exception: Stack<>::pop(): empty stack

Template Argument Deduction

Template argument deduction is a feature that automatically deduces (understands) the data type of the argument passed to a function or class template. Instead of explicitly specifying template arguments, the compiler figures them out for you.

Example

Lets see an example of the Template Argument Deduction −

template<typenameT>
T add(T a, T b){return a + b;}intmain(){// The compiler deduces T as intauto result1 =add(5,3);// The compiler deduces T as doubleauto result2 =add(3.14,2.86);}

In this code, we didn’t write add<int>(5,3) or add<double>(3.14, 2.86). The compiler deduces the type based on the arguments you provide.

Function Template Argument Deduction

In C++ Function template argument is a feature that allows the compiler to automatically deduce the types of template parameters based on the arguments passed to the function.

Example

Heres a simple example of a Function template argument deduction.

#include <iostream>// Function templatetemplate<typenameT>voidprintValue(T value){
   std::cout << value << std::endl;}intmain(){// Usage examplesprintValue(42);// T is intprintValue("Hello");// T is const char*printValue(3.14159);// T is doublereturn0;}

Output

42
Hello
3.14159

Class Template Argument Deduction

Class template argument deduction in C++ is a feature that enables the compiler to automatically infer template parameters for class templates from the constructor arguments when creating an object.

Example

Heres a basic implementation of class template deduction.

#include <iostream>template<typenameT>classHolder{public:Holder(T value):data(value){}voidshow()const{ std::cout << data << std::endl;}private:
      T data;};intmain(){
   Holder h1(42);// T deduced as int
   Holder h2(3.14);// T deduced as double
   Holder h3("Hello");// T deduced as const char*

   h1.show();// Output: 42
   h2.show();// Output: 3.14
   h3.show();// Output: Helloreturn0;}

Output

42
3.14
Hello

Benefits of C++ Templates

  • Code Reusability − Templates enable you to write generic code that works with all data types, thus eliminating the need to write identical code for each required type. This saves development time by reducing code duplication.
  • Reduced Maintenance − Update a template and see the changes across all instantiations. Which applies better in terms of bug fixing, fixing ones, and seeing the benefits of all the instantiations.
  • Enhanced Performance − Template instantiations occur at compile time, reducing run time errors. The compiler optimizes the code for specific data types.
  • Organize the code better − Since templates separate the algorithmic logic from the data type it helps in creating modular code which further is good in terms of development scenario. It helps reduce searching for different implementations of a code.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *