Do you think IIT Guwahati certified course can help you in your career?
No
Introduction
Templates in C++ are like a set of instructions or a blueprint for creating similar things, like cookies from a cookie cutter. You can use the same template to make many cookies of the same shape and size, but you can use different ingredients to make different types of cookies. In the same way, you can use the same template in C++ to create many similar pieces of code but with different types of data.
Templates in C++ are a powerful feature that allows you to write generic and reusable code. They enable you to define functions and classes with placeholder types, which can be specified later when the function or class is instantiated. This mechanism allows the same code to work with different data types without duplicating code for each type.
Templates can be represented as:
How Do Templates Work?
Templates work by providing a blueprint for functions or classes that can operate with any data type. When you use a template, the C++ compiler generates specific versions of the template based on the types you provide. Here’s how they work:
1. Template Definition:
You define a template with placeholder types, which are used within the function or class.
Example:
template <typename T>
T max(T a, T b)
{
return (a > b) ? a : b;
}
2. Template Instantiation:
When you call a template function or create an instance of a template class, the compiler replaces the placeholder type with the actual type you provide.
Example:
int result = max(10, 20); // T is int
double result2 = max(10.5, 20.5); // T is double
3. Code Generation:
The compiler generates specific code for each type used with the template. For the above example, it creates separate versions of max for int and double.
Types of Template
The two main types of templates in C++:
Class Templates
Functions Templates
1. Class Templates in C++
Syntax of Class Templates in C++
Here's a syntax of a template class:
template <typename T>
class MyClass {
// Class definition here
};
Example of Class Templates
C++
C++
#include <iostream> #include <vector> #include <utility> using namespace std;
template <typename T, typename U> class Map { private: std::vector<std::pair<T, U>> data; public: Map() {} void insert(T key, U value) { data.push_back(std::make_pair(key, value)); } U getValue(T key) { for (auto item : data) { if (item.first == key) { return item.second; } } return U(); } };
A class template called "Map" that can store key-value pairs where the key is of type "T" and the value is of type "U". The template types can be replaced with any data type when an object of the class is created.
The class has a private member variable called "data" which is a vector of pairs of type T and U.
It has a default constructor and two public member functions: insert() function to insert key-value pairs, getValue() function to retrieve the value associated with a specific key.
In the main function, we create an object of the class with T=int, and U=string, insert some key-value pairs, retrieve the value associated with a key 2 and output it to the console.
Output
Class template with multiple parameters
It works similarly to class templates, but they define a single function instead of a class. The function can take multiple parameters, some or all of which can be template types. The function is then instantiated with specific types for the template parameters when it is called.
You can also use a template with multiple parameters like this:
template <typename T, typename U>
class MyClass {
// Body
};
//OR
template <typename T, int N>
class MyClass {
// Body
};
Non-Type Template Arguments
We may use non-type arguments as well as many arguments in the template. In addition to the type T parameter, we can utilize strings, function names, constant expressions, and built-in types as arguments. Consider the following example:
template<class T, int size>
class array
{
T arr[size]; // automatic array initialization.
};
In the above case, the nontype template argument is size and therefore, template supplies the size of the array as an argument.
Functions Templates in C++
C++ template functions are a type of feature that allows the creation of generic functions. These functions can operate on multiple data types rather than being limited to a specific type.
Syntax of Functions Templates in C++
Syntax of a c++ template function:
template <typename T>
T findMax(T arr[], int size) {
// Function definition here
};
In both examples, the "typename T" is the template parameter. It can be named anything, but "T" is a common convention. When the template is instantiated, the type passed as the template argument will replace T.
Example of Function Templates
C++
C++
#include <iostream> using namespace std;
template <typename T> void printArray(T* arr, int size) { for (int i = 0; i < size; i++) { cout << arr[i] << " "; } cout << endl; }
In the main function, an array of integers is declared and initialized with values {1, 2, 3, 4, 5}. The printArray function is then called, passing the array and its size as arguments. This will print out each element of the array on a separate line.
You can also use this function template with other types, such as float, double, string, etc.
Output
For float datatype,
Example of Function Templates with Multiple Parameters
The above code will define a function template that takes two template parameters, T and U, and prints out the values of two parameters passed to it. In the main function, the function template is instantiated with different types for T and U and passed with different values, and it will print out the values.
Output
Overloading a Function Template in C++
We can overload the generic function, which means that the argument list of the overloaded template functions can differ. Let's understand this through a simple example:
C++
C++
#include <iostream> using namespace std; template<class X> void fun(X a) { std::cout << "Value of a is : " <<a<< std::endl; } template<class X,class Y> void fun(X b ,Y c) { std::cout << "Value of b is : " <<b<< std::endl; std::cout << "Value of c is : " <<c<< std::endl; } int main() { fun(30); fun(50,20.5); return 0; }
You can also try this code with Online C++ Compiler
In the above example, the template of fun() function is overloaded.
Restrictions of Generic Functions
Except for the data type, generic functions do the identical operation in all variants of a function. Let's look at a basic example of an overloaded function that cannot be substituted by a generic function because the functions have different functions.
C++
C++
#include <iostream> using namespace std; void fun(double var1) { cout<<"value of a is : "<<var1<<'\n'; }
void fun(int var2) { if(var2%2==0) { cout<<"Number is even"; } else { cout<<"Number is odd"; }
}
int main() { fun(4.6); fun(6); return 0; }
You can also try this code with Online C++ Compiler
The ordinary functions are overloaded in the above example. We cannot overload the generic functions because they serve distinct purposes. The first displays the value, and the second decides if the number is even or odd.
Advantages of Using Templates in C++
When we use the template in C++, it provides several advantages:
It enables code reuse by allowing the definition of generic algorithms or data structures that can operate on different data types.
It supports generic programming, where algorithms and data structures can be designed without specifying concrete types.
It can ensure type safety at compile-time.
It can facilitate the generation of optimized code specific to each data type.
The C++ Standard Library extensively uses templates to provide a wide range of generic algorithms, containers, and data structures.
It allows customization through template arguments.
Template Argument Deduction
Template argument deduction in C++ refers to the process by which the compiler determines the template arguments for a function or class template based on the arguments passed to it. When a function template is called without explicitly specifying template arguments, the compiler deduces the template arguments by analyzing the types of the function arguments.
For example:
template<typename T>
void print(T value) {
std::cout << value << std::endl;
}
int main() {
print(5); // Deduces T as int
print("Hello"); // Deduces T as const char*
return 0;
}
In this example, the compiler deduces the template argument T as int for the first function call and as const char* for the second function call.
Difference between Function Overloading and Templates in C++
Parameters
Function Overloading
Templates
Definition
Allows multiple functions with the same name but different parameters.
Allows defining functions or classes with placeholder types that can be specified later.
Type Handling
Functions are overloaded based on the number and types of parameters.
Templates handle different types generically and instantiate specific versions based on the type provided.
Implementation
Each overloaded function is a separate function with its own implementation.
A single template definition is used to generate multiple versions based on the type.
Type Safety
Type checking is done at compile-time based on the function signatures.
Type safety is maintained through template type parameters, with specific type checks at compile-time.
Code Reusability
Requires separate function definitions for each parameter type.
Provides a single definition that works with any data type, enhancing code reusability.
Function Resolution
The compiler chooses the correct function based on the number and types of arguments.
The compiler generates specific instances of the template based on the types used when calling the template.
Support for Multiple Types
Limited to different parameter lists for the same function name.
Can handle any number of types through a single template definition.
Specialization
Cannot specialize functions based on parameter types.
Supports specialization to handle specific types differently.
Syntax Complexity
Simpler syntax with direct function definitions.
More complex syntax involving template parameters and instantiation.
typename VS class keyword
Aspect
typename
class
Purpose
Indicates that a dependent name is a type
Declares a user-defined type (class)
Usage
Used in templates to specify that a dependent name is a type
Used to define a class or a class template
Syntax
typename T
class MyClass { ... }
Meaning
T is a type that will be deduced by the compiler
MyClass is a user-defined type
Compilation
Resolved at compile-time based on template arguments
Compiled into object code
Access Specifiers
Not applicable
public, private, protected
Member Functions
Not applicable
Can have member functions
Inheritance
Not applicable
Supports inheritance
Templates
Used within template declarations and definitions
Can be used to create class templates
Disambiguation
Disambiguates types from non-types in dependent contexts
Not used for disambiguation
Frequently Asked Questions
What is the difference between a class template and a function template?
A class template defines a blueprint for a class with generic types, while a function template specifies a function that can operate with any type.
What is a C++ function template?
A C++ function template allows functions to operate on generic types, enabling code reusability for different data types without rewriting code.
What is the use of a template?
Templates in C++ are used for code reusability and type safety, allowing developers to write generic and flexible code that works with any data type.
Conclusion
We have discussed what a template in C++ is. Template in C++ is a cornerstone of generic programming, allowing you to create flexible and reusable code by defining functions and classes that operate with any data type. By using templates, you can avoid code duplication, ensure type safety, and handle a variety of data types with a single implementation.
For more articles like the C++ template function, you can look at the following: