Skip to content
  • Function Templates · C++

Function Templates

LearnViaNotes @learnvianotes· 3 min read

A template is a blueprint the compiler stamps out for each set of types you use it with. Write the algorithm once; get type-checked, fully optimised code for every type.

Defining and calling

C++
#include <iostream>
#include <string>

template <typename T>                     // `class T` means the same
T maxOf(T a, T b) { return a > b ? a : b; }

template <typename T, typename U>
auto add(T a, U b) { return a + b; }      // return type deduced from the expression

template <typename T, int N>              // non-type template parameter
constexpr int length(const T (&)[N]) { return N; }

int main() {
    std::cout << maxOf(3, 7) << ' ' << maxOf(2.5, 1.5) << ' ' << maxOf<std::string>("pear", "apple") << '\n';
    std::cout << add(1, 2.5) << '\n';
    int arr[] = {1, 2, 3, 4};
    std::cout << length(arr) << '\n';
    // maxOf(3, 7.0);   // error: T deduced as both int and double
    std::cout << maxOf<double>(3, 7.5) << '\n';   // explicit template argument
}
Output
7 2.5 pear
3.5
4
7.5

How instantiation works

  1. Deduction

    From the call maxOf(3, 7) the compiler deduces T = int.

  2. Instantiation

    It generates int maxOf<int>(int, int) — a real function — and type-checks it.

  3. Reuse

    Every call with T = int in this translation unit uses the same instantiation; identical instantiations in other TUs are merged by the linker.

Overloading and explicit specialisation

C++
#include <cstring>
#include <iostream>

template <typename T>
bool equal(const T& a, const T& b) { return a == b; }

template <>                                               // full specialisation for const char*
bool equal<const char*>(const char* const& a, const char* const& b) { return std::strcmp(a, b) == 0; }

template <typename T>
void describe(T)  { std::cout << "value\n"; }
template <typename T>
void describe(T*) { std::cout << "pointer\n"; }           // overload: more specialised, preferred

int main() {
    const char* x = "hi";
    char buf[] = "hi";
    const char* y = buf;
    std::cout << equal(1, 1) << equal(x, y) << '\n';     // compares contents, not addresses
    int n = 0;
    describe(n);
    describe(&n);
}
Output
11
value
pointer

Abbreviated templates (C++20)

C++
#include <iostream>
#include <vector>
auto sum(const auto& container) {          // `auto` parameter = implicit template
    typename std::decay_t<decltype(container)>::value_type total{};
    for (const auto& x : container) total += x;
    return total;
}
int main() {
    std::cout << sum(std::vector<int>{1, 2, 3}) << ' ' << sum(std::vector<double>{0.5, 0.25}) << '\n';
}
Output
6 0.75

What is template argument deduction?

Do templates cause code bloat?

Free for students and teachers

Write notes like this one

Cards for every idea, quizzes and flashcards, read aloud — on the web and your phone.

Something wrong with this note? Open it to report