---
title: "C++ Template Function Tutorial"
url: https://weworkworldwide.com/tutorials/c-template-function-2/
description: "C++ Template Function Tutorial: There are times that we want to run the same task on multiple different data-types."
date: 2026-11-14T17:00:03+00:00
source: https://weworkworldwide.com/llms.txt
---

# C++ Template Function Tutorial

“Don’t let the noise of other’s opinion drown out your own inner voice” Steve Jobs

There are times that we want to run the same task on multiple different data-types.

One way to do this is by creating multiple functions, each takes a list of arguments but with different data-types and all these functions do the same task.

Example:

``` line-numbers
#include <iostream>
using namespace std;
void sum(double a, double b){
cout<<"Double-type function"<<endl;
cout<< a +b<<endl;
}
void sum(int a , int b){
cout<<"Integer-type function"<<endl;
cout<<a +b<<endl;
}
int main() {
sum(2,3);
sum(2.4, 34.22);
return 0;
}
```

Output:

Integer-type function

5

Double-type function

36.62

Note: please check the *function overloading* section if you don’t know how we used a function’s name twice.

In the example above, we’ve overloaded the same function `sum()` two times to be able to work with integer and float numbers as the arguments.

Now let’s refactor the source code above, but this time we will use function-templates:

``` line-numbers
#include <iostream>
using namespace std;
template<typename T>
void sum(T a , T b){
cout<<a+b<<endl;
}
int main() {
sum(2,3);
sum(2.4, 34.22);
return 0;
}
```

Output:

5

36.62

In the example above, the data-type of the parameters within `sum()` function is something we made up via `typename` keyword (could be anything else like `Jack`, `Ellen` etc.). This data-type name is simply a placeholder.

When the call to the `sum()` function happened within the body of the `main()` function, behind the scene the compiler will check the data-type of the arguments in each call to this function and based on that, it will generate a **function-definition** that has the structure and instructions of the **`sum` function-temple** and the correct data type that matches the arguments and it will use this generated function to handle the call.

So in this example the first call to the `sum()` function was:

``` line-numbers
sum(2,3);
```

And because the type of these two numbers is `int`, behind the scene the compiler uses the template function to generate a function definition that is equal to this:

``` line-numbers
void sum( int a, int b){
cout<< a + b<<endl;
}
```

Also the next time the call to the `sum()` function happened, again the compiler checked the data-type of the arguments and realized that this time we called the function with values of type `double`. Here the compiler generates another function-definition but this time the type of parameters is `double`.

``` line-numbers
void sum( double a, double b){
cout<< a + b<<endl;
}
```

As you can see, with `function-template` we can simply create a template with all sorts of tasks that needs to be done within the body of the template and allow the compiler to automatically generate function-definitions as many as necessary.

When we call a function-template in the source-code and put values as its argument, behind the scene the compiler will automatically check the type of these values, and it will generate a function definition based on the `function-template` and the data-type of the input values.

Just like functions, function-templates have two parts:

1.  Template-declaration

2.  Template- definition

Note: if we put the Template-definition on top of the `main()` function, there’s no need to declare the template-declaration as well.

## Function-Template declaration:

This is simply the prototype of the function-template:

``` line-numbers
template <typename name> data-type function-name (data-type a, data-type n);
`template`: in order to create a function-template, we first start with the keyword `template`.
`<>`: followed by the keyword `template` we use angle brackets `<>` and within it, we set one or more type-names.
`typename`: we use the `typename` keyword to create names that can be used instead of the real data-types of parameters as well as return data-type of the function.
```

Note: instead of the name `typename` we could also use the keyword `class` as well.

``` line-numbers
For example: template <typename Jack> void sum( Jack a, Jack b);
```

Now when we call the `sum` function with arguments, compiler will first check the data-type of the arguments. Then it will generate a function-definition from this template and replace each input’s data type with the names we used for data-types of the parameters.

For example, let’s say we called the `sum()` function with the values of 10 and 15 like: `sum(10,15);`.

Now the compiler realizes that the data-type of the first argument is `int` and it will link the `int` with `Jack`.

This means in the generated function, all those data-types that are named `Jack` will be replaced with `int` data-type.

``` line-numbers
Note: in case of `sum()` function, if we put two arguments in the function, each of different data-type, we will get a compile time error because we used one name `Jack` for both parameters and now the data-type of the first argument is considered as the replacement of the name `Jack` but the second argument is also trying to use a different data-type for this name and that's why the compiler will return error.
```

Example:

``` line-numbers
#include <iostream>
using namespace std;
template<typename T>
void sum(T a , T b){
cout<<a+b<<endl;
}
int main() {
sum(2,3.55);
return 0;
}
```

Output:

error: no matching function for call to ‘sum(int, double)’

``` line-numbers
sum(2,3.55);
```

Here, when we called the `sum()` function, we put two arguments of type `int` and `double` respectively. But in the function-template for both parameters we used the same name. And now because there’re two data-types for one name, the compiler retuned error.

``` line-numbers
`data-type`: data-type can be set to either the name created via `typename` keyword or we can explicitly set a known data-type for a parameter or the return data-type of the function.
Note: we could also create two or more names via `typename` keyword and use each one as the placeholder for parameter's data-type.
```

Example:

``` line-numbers
#include <iostream>
using namespace std;
template<typename T, typename S>
void sum(T a , S b){
cout<<a+b<<endl;
}
int main() {
sum(2,3.55);
return 0;
}
```

Output: 5.55

In this example, the function-template named `sum`, has two parameters each with different name for its data-type. So here we’re allowed to use two values each with different data-type when calling the `sum` function, and behind the scene the compiler will generate a function-definition that replaces the first data-type of the first parameter with the data-type of the first argument and the data-type of the second parameter with the data-type of the second argument.

Basically the generated function would be like this when the call to the `sum` function happened:

``` line-numbers
void sum(int a , double b){…}
```

## Function-Template- definition:

The compiler will generate functions from our function-template and for the body of the generated function (including tasks that should be done within this body) it will use the body of the function-template-definition.

The same structure of the template-declaration applies to template-definition + the body in which we can use to write the tasks that should be done. (These tasks will be copied to the generated function-definition)

Example:

``` line-numbers
template (typename T)void sum (T a, T b){
```

//body of the function-template

``` line-numbers
}
```

## Overloaded Templates:

Just like functions, function-templates can also be overloaded. In this case, based on the type of arguments we put when calling a function-template, behind the scene the compiler will check all the overloaded function-templates and deduce which one to choose in order to generate the function-definition from.

Example:

``` line-numbers
#include <iostream>
using namespace std;
template <typename T>
void sum (T a, T b){
cout<< "message from T"<<endl;
}
template <typename A>
void sum(A *a, A *b){
cout<< "message from A"<<endl;
}
int main() {
sum(1,2);
int i = 100;
int b = 200;
sum(&i, &b);
return 0;
}
```

Output:

message from T

message from A

In the example above, we have two function-templates named `sum`. But one of them accepts actual values (which can be integer values, double, objects etc.) but the other one accepts the memory address of these types of values.

Note: check the *pointers section* to learn more about memory address.

So whenever we call the `sum` function with basic data-types (Just like the first time the `sum` function is called in the body of the `main()` function) the first function-template will be used to generate the function-definition and whenever we call the `sum` function and assign memory-addresses as its arguments (Just like the second time the `sum` function is called in the body of the `main()` function), the second function-template will be called to generate the function-definition.

## Explicit Template Specialization:

Consider the template-function named `sum` that we used in the previous examples. The structure of the template was `template <typename T> void sum(T a, T b)`. This template basically accepts two arguments of any type.

With the help of `explicit-template-specialization` we can overload the `sum` template and create another one that will be used only when arguments of specific data-type is set when calling the `sum()` function.

Example:

``` line-numbers
#include <iostream>
using namespace std;
template <typename T>
void sum (T a, T b){
cout<< "message from T"<<endl;
}
```

template<>

``` line-numbers
void sum<char>(char a, char b){
cout<<"message from char"<<endl;
}
int main() {
sum(1,2);
int i = 100;
int b = 200;
sum('a','b');
return 0;
}
```

Output:

message from T

message from char

As you can see, when we overloaded the `sum` function-template, we used ` template<>

``` line-numbers
void sum<char>(char a, char b)`.
```

In order to create Template-Specialization:

-   After the keyword `template` we use empty angle  
    brackets.

Note: this is because the data-types for parameters and returned data-type should be explicitly declared.

-   After the name of the template-function we use angle-brackets and  
    within it, we declare the target data-type that this function-template  
    should be used for.

-   Of course the data-type of the parameters now should be the same  
    as the declared data-type in the angle-brackets.

From now on, any time the `sum()` function is called and the data-type of its arguments was `char`, the Explicit-Template-Specialization will be the target template that the compiler will use as the function-definition.

And that’s how the second time we called the `sum()` within the body of the `main()` function, because the data-type of the arguments was `char`, we got the output that is coming from the `sum` explicit-specialization’s body.

## Explicit-Instantiation:

When working with Template-functions, it’s the compiler that will deduce what data-type it should use when generating the function-definition of a template-function.

But when calling a function-template and assigning arguments to the function, we can explicitly tell the compiler what data-type it should use when generating the function-definition. This is called Explicit-Instantiation.

Example:

``` line-numbers
#include <iostream>
using namespace std;
template<typename T, typename S>
void sum(T a , S b){
cout<<a+b<<endl;
}
int main() {
sum<int, float>(2,3.55);
return 0;
}
```

Output:

5.5

Within the body of the `main()` function, we called the `sum()` but this time we used explicit instantiation by adding the angle brackets after the name `sum` and putting the data-type for the parameters respectively.

Note: here because each parameter had different name (created via `typename` keyword) in the function-template, we needed to set two data-types each separated via comma. If there was only one `name` set for all the parameters in the function-template, then in that case we could only use one data-type in the angle brackets.
