Function templates
What you'll learn:
- write a function template and a class template;
- explain how the compiler deduces the type
Tand when it is given explicitly; - give a template a separate version for one type;
- write a function that takes any number of arguments.

Picture a star-shaped cookie cutter. It is made once and then pressed into any dough: shortbread, chocolate, ginger. You get separate cookies of one shape, each with its own dough.
A template in C++ works like such a cutter. The shape is the function's body, and the dough is the type it works with. Where the picture stops working: a cutter cuts any number of cookies from one dough, while the compiler creates the version for a type once and then reuses it.
Why does this matter? The overloads twice(int) and twice(double) differ only in type, while their bodies are the same: return x * 2;. long and float would need two more copies of it. A function template writes the body once, and the compiler creates the versions for the needed types itself:
#include <iostream>
template <typename T>
T twice(T x) {
return x * 2;
}
int main() {
std::cout << twice(21) << ' ' << twice(1.25) << '\n'; // 42 2.5
}Template parameter
A function template is a blueprint from which the compiler builds ordinary functions. The line template <typename T> declares a template parameter T, a name that stands for a type. In the parameters, the return type and the body, T stands where an ordinary function would have int or double.
The name T is only a convention: Value works too. class may be written instead of typename.
Instantiation
For the call twice(21), the compiler substitutes int for T and gets the function int twice(int x). This is instantiation: a function for a specific type is created from the template. The call twice(1.25) creates a second function, double twice(double x). Another call with an int uses the version already created.
The compiler checks the template's body separately for each type. For int and double, the expression x * 2 is valid. But a std::string cannot be multiplied by 2, so the call twice(std::string("ab")) does not compile, even though the template itself is correct.
Templates in headers
To create the int version, the compiler needs the template's body; a declaration alone is not enough. That is why the template usually goes in the header twice.h together with its body:
#pragma once
template <typename T>
T twice(T x) {
return x * 2;
}If a header with an ordinary function is included in two .cpp files, the build stops on a multiple definition error. A template does not have this problem. The one definition rule allows identical definitions of a template in different translation units, as it does for inline functions.
Common mistake
The template is split like an ordinary function: twice.h keeps the declaration template <typename T> T twice(T x);, and the body moves to twice.cpp. Both files compile, but the build clang++ main.cpp twice.cpp fails:
#include <iostream>
#include "twice.h"
int main() {
std::cout << twice(21) << '\n'; // ✗
}undefined reference to `int twice<int>(int)'This message comes from the linker. In the course exercises it says the same thing in other words: undefined symbol. twice.cpp has no call with an int, so the int version is not created there. main.cpp has no body of the template, so the version cannot be created there either. Move the body into twice.h.
Key points
- A function template writes the body once, and the compiler creates the version for each type itself.
- Instantiation creates a function from the template for a specific type, one version per type.
- The template's body goes in the header: without the body the compiler cannot create a version.
Subscribe to take the course
The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.