A function template in C++ allows you to define a function that works with any data type. Instead of writing multiple versions of a function for different types, a function template enables you to write a single generic function that can handle multiple types of arguments. The exact type to be used is determined at compile-time, when the function is invoked.
Function templates provide the flexibility to create generic, reusable code that operates with a variety of types, enhancing code maintainability and readability.
To define a function template, you use the template keyword followed by a template parameter list enclosed in angle brackets (< >). The template parameter acts as a placeholder for the type that will be specified when the function is called.
template <typename T>
T function_name(T arg1, T arg2) {
// function body
}
Here:
template <typename T>: This defines a template parameter T, which represents a type that will be substituted when the function is called.T function_name(T arg1, T arg2): The function function_name takes two arguments of type T and returns a result of type T.#include <iostream>
using namespace std;
// Function template to add two values
template <typename T>
T add(T a, T b) {
return a + b;
}
int main() {
cout << add(5, 3) << endl; // T is int
cout << add(3.5, 2.7) << endl; // T is double
cout << add(1.2f, 2.3f) << endl; // T is float
return 0;
}
Output:
8
6.2
3.5
add, the template parameter T allows the function to work with any type, such as int, double, or float. When the function is called in main(), the compiler automatically deduces the type of T based on the type of the arguments passed.add functions for int, double, float, etc.You can define a function template that accepts multiple parameters of different types. Each parameter can have its own template type.
template <typename T, typename U>
auto multiply(T a, U b) -> decltype(a * b) {
return a * b;
}
int main() {
cout << multiply(3, 4.5) << endl; // T is int, U is double
cout << multiply(2.5, 4.5) << endl; // T and U are both double
return 0;
}
Output:
13.5
11.25
multiply function takes two parameters a and b of types T and U respectively. The return type is automatically deduced using decltype(a * b), which evaluates the type of the product of a and b.You can also provide default values for the template parameters. If a type is not explicitly specified when the function is called, the default type will be used.
template <typename T = int> // Default type is int
T square(T x) {
return x * x;
}
int main() {
cout << square(4) << endl; // Uses default type 'int'
cout << square(3.5) << endl; // T is double
return 0;
}
Output:
16
12.25
T has a default type of int. If no type is specified when calling square, int will be used. However, if a different type (e.g., double) is provided, the template will adapt accordingly.You can overload a function template by defining multiple versions of a function template with different numbers or types of parameters.
template <typename T>
void print(T t) {
cout << "Printing value: " << t << endl;
}
template <typename T, typename U>
void print(T t, U u) {
cout << "Printing values: " << t << " and " << u << endl;
}
int main() {
print(5); // Single argument (int)
print(3.14, "Hello"); // Two arguments (double and string)
return 0;
}
Output:
Printing value: 5
Printing values: 3.14 and Hello
print function template are defined: one for printing a single argument and another for printing two arguments.In C++, when calling a function template, the compiler tries to deduce the type of the template parameter based on the arguments passed. This process is known as template argument deduction.
template <typename T>
void print(T value) {
cout << "Value: " << value << endl;
}
int main() {
int x = 10;
print(x); // T is deduced as int
print(3.14); // T is deduced as double
return 0;
}
Output:
Value: 10
Value: 3.14
T is int when x (an integer) is passed to print, and T is double when the literal 3.14 is passed.SFINAE is a feature of C++ that allows you to enable or disable function templates based on certain conditions. It is used to create type traits or conditional template instantiations.
You can use SFINAE to enable a function template only if a specific condition is met, such as if a type has certain properties (e.g., if it's an integer type or a floating-point type).
#include <iostream>
#include <type_traits>
using namespace std;
template <typename T>
typename std::enable_if<std::is_integral<T>::value>::type print(T value) {
cout << "Integral value: " << value << endl;
}
template <typename T>
typename std::enable_if<std::is_floating_point<T>::value>::type print(T value) {
cout << "Floating-point value: " << value << endl;
}
int main() {
print(10); // Integral type
print(3.14); // Floating-point type
return 0;
}
Output:
Integral value: 10
Floating-point value: 3.14
std::enable_if in conjunction with std::is_integral and std::is_floating_point to selectively enable function templates based on the type of the argument.int, long, etc.), and the second is enabled for floating-point types (float, double, etc.).Function Templates: A template for creating functions that can work with any data type. The actual type is specified when the function is called.
Template Parameters: Template parameters can be of any type (e.g., T) and can be specialized for different types or used with non-type parameters like constants or integers.
Multiple Template Parameters: Functions can have more than one template parameter, enabling functions to operate with multiple data types.
Default Template Arguments: You can provide default values for template parameters, so they don't have to be specified every time.
Overloading Templates: Functions can be overloaded based on the number or types of template parameters.
Template Argument Deduction: The compiler can automatically deduce the template argument based on the function call, making template functions very flexible.
SFINAE: Used to enable or disable certain function templates based on type properties (e.g., integral, floating-point).
Advantages:
Disadvantages:
Function templates are one of the most powerful features in C++ that enable the writing of flexible, type-independent functions.
Open this section to load past papers