Step 1 of 8
Function templates
Suppose you want a biggest(a, b) function for ints, for doubles and for strings. Without templates you'd write three nearly identical functions. A template lets you write it once, with a placeholder for the type. The compiler then generates a real function for each type you actually use.
#include <iostream>
#include <string>
template <typename T>
T biggest(T a, T b) {
return a > b ? a : b;
}
template <typename T>
void show_twice(const T& x) {
std::cout << x << " " << x << "\n";
}
int main() {
std::cout << biggest(3, 9) << "\n"; // T = int
std::cout << biggest(2.5, 1.0) << "\n"; // T = double
std::cout << biggest<std::string>("pear", "apple") << "\n";
show_twice('z');
show_twice(std::string("hey"));
}
9
2.5
pear
z z
hey hey
How it works
template <typename T>introduces a type parameter namedT. Inside the function,Tis used like any type.- When you call
biggest(3, 9), the compiler deducesT = intfrom the arguments and generatesint biggest(int, int). That's called instantiation. It happens at compile time, so templates cost nothing at run time. - You can also name the type yourself:
biggest<std::string>("pear", "apple"). Here that's needed, because the arguments are string literals (const char*), and comparing two pointers with>wouldn't compare the text. - The template only works for types that support what the body does.
biggestneeds>;show_twiceneeds<<.
Common mistakes
- Mixing types:
biggest(3, 2.5)fails, becauseTcan't be bothintanddouble. Writebiggest<double>(3, 2.5)or pass matching types. - Putting a template's definition in a
.cppfile and only its declaration in a header. The compiler needs the whole body wherever the template is used, so templates normally live entirely in headers.
Your turn: make clamp_value a template.