
- C++ Home
- C++ Overview
- C++ Environment Setup
- C++ Basic Syntax
- C++ Comments
- C++ Hello World
- C++ Omitting Namespace
- C++ Tokens
- C++ Constants/Literals
- C++ Keywords
- C++ Identifiers
- C++ Data Types
- C++ Numeric Data Types
- C++ Character Data Type
- C++ Boolean Data Type
- C++ Variable Types
- C++ Variable Scope
- C++ Multiple Variables
- C++ Basic Input/Output
- C++ Modifier Types
- C++ Storage Classes
- C++ Numbers
- C++ Enumeration
- C++ Enum Class
- C++ References
- C++ Date & Time
- C++ Operators
- C++ Arithmetic Operators
- C++ Relational Operators
- C++ Logical Operators
- C++ Bitwise Operators
- C++ Assignment Operators
- C++ sizeof Operator
- C++ Conditional Operator
- C++ Comma Operator
- C++ Member Operators
- C++ Casting Operators
- C++ Pointer Operators
- C++ Operators Precedence
- C++ Unary Operators
- C++ Control Statements
- C++ Decision Making
- C++ if Statement
- C++ if else Statement
- C++ Nested if Statements
- C++ switch Statement
- C++ Nested switch Statements
- C++ Loop Types
- C++ while Loop
- C++ for Loop
- C++ do while Loop
- C++ Foreach Loop
- C++ Nested Loops
- C++ break Statement
- C++ continue Statement
- C++ goto Statement
- C++ Strings
- C++ Strings
- C++ Loop Through a String
- C++ String Length
- C++ String Concatenation
- C++ String Comparison
- C++ Functions
- C++ Functions
- C++ Multiple Function Parameters
- C++ Recursive Function
- C++ Return Values
- C++ Function Overloading
- C++ Function Overriding
- C++ Default Arguments
- C++ Arrays
- C++ Arrays
- C++ Multidimensional Arrays
- C++ Pointer to an Array
- C++ Passing Arrays to Functions
- C++ Return Array from Functions
- C++ Structure & Union
- C++ Structures
- C++ Unions
- C++ Pointers
- C++ Pointers
- C++ Dereferencing
- C++ Modify Pointers
- C++ Class and Objects
- C++ Object Oriented
- C++ Classes & Objects
- C++ Class Member Functions
- C++ Class Access Modifiers
- C++ Static Class Members
- C++ Static Data Members
- C++ Static Member Function
- C++ Inline Functions
- C++ this Pointer
- C++ Friend Functions
- C++ Pointer to Classes
- C++ Constructors
- C++ Constructor & Destructor
- C++ Default Constructors
- C++ Parameterized Constructors
- C++ Copy Constructor
- C++ Constructor Overloading
- C++ Constructor with Default Arguments
- C++ Delegating Constructors
- C++ Constructor Initialization List
- C++ Dynamic Initialization Using Constructors
- C++ Object-oriented
- C++ Overloading
- C++ Polymorphism
- C++ Abstraction
- C++ Encapsulation
- C++ Interfaces
- C++ Virtual Function
- C++ Pure Virtual Functions & Abstract Classes
- C++ File Handling
- C++ Files and Streams
- C++ Reading From File
- C++ Advanced
- C++ Exception Handling
- C++ Dynamic Memory
- C++ Namespaces
- C++ Templates
- C++ Preprocessor
- C++ Signal Handling
- C++ Multithreading
- C++ Web Programming
- C++ Socket Programming
- C++ Concurrency
- C++ Advanced Concepts
- C++ Lambda Expression
- C++ unordered_multiset
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 <typename identifier> 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> using namespace std; template <typename T> inline T const& Max (T const& a, T const& b) { return a < b ? b:a; } int main () { 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; return 0; }
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 <class type> class class-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> using namespace std; template <class T> class Stack { private: vector<T> elems; // elements public: void push(T const&); // push element void pop(); // pop element T top() const; // return top element bool empty() const { // return true if empty. return elems.empty(); } }; template <class T> void Stack<T>::push (T const& elem) { // append copy of passed element elems.push_back(elem); } template <class T> void Stack<T>::pop () { if (elems.empty()) { throw out_of_range("Stack<>::pop(): empty stack"); } // remove last element elems.pop_back(); } template <class T> T Stack<T>::top () const { if (elems.empty()) { throw out_of_range("Stack<>::top(): empty stack"); } // return copy of last element return elems.back(); } int main() { 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<typename T> T add(T a, T b) { return a + b; } int main() { // The compiler deduces T as int auto result1 = add(5, 3); // The compiler deduces T as double auto 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 template template<typename T> void printValue(T value) { std::cout << value << std::endl; } int main() { // Usage examples printValue(42); // T is int printValue("Hello"); // T is const char* printValue(3.14159); // T is double return 0; }
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<typename T> class Holder { public: Holder(T value) : data(value) {} void show() const { std::cout << data << std::endl; } private: T data; }; int main() { 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: Hello return 0; }
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.