Templates in C++

    Atul Kabra4 min readUpdated

    A template lets you write a function or class once and use it with any type. Instead of writing maxInt, maxDouble, and maxString, you write one max template and the compiler generates the right version for each type you call it with. Templates are how the C++ Standard Library provides std::vector, std::map, and the rest — one definition, infinite element types. This is called generic programming.

    Here is the smallest useful template.

    A function template

    The template <typename T> line introduces a placeholder type T that the compiler fills in per call.

    #include <iostream>
    #include <string>
    
    // works for any type that supports >
    template <typename T>
    T largest(const T& a, const T& b) {
        return (a > b) ? a : b;
    }
    
    int main() {
        std::cout << largest(3, 7) << "\n";           // T = int   -> 7
        std::cout << largest(2.5, 1.1) << "\n";        // T = double -> 2.5
        std::cout << largest<std::string>("ab", "cd") << "\n"; // T = string -> cd
    }
    

    The compiler reads largest(3, 7), deduces T = int, and stamps out an int version. This stamping-out is called template instantiation. You usually do not state the type — the compiler deduces it from the arguments.

    A class template

    Class templates generalise the type they store or operate on. Here is a tiny generic pair-like box.

    #include <iostream>
    #include <string>
    
    template <typename T>
    class Box {
        T value;                         // stores any type T
    public:
        explicit Box(T v) : value(std::move(v)) {}
        const T& get() const { return value; }
    };
    
    int main() {
        Box<int> a{42};
        Box<std::string> b{"hello"};     // a different instantiation
        std::cout << a.get() << " " << b.get() << "\n";  // 42 hello
    }
    

    Box<int> and Box<std::string> are two distinct classes generated from one template. For class templates you typically write the type explicitly in angle brackets (though C++17 can often deduce it too).

    Want to learn this properly?

    Join the waitlist for our courses — beginner-friendly, project-first classes in Jalgaon.

    Browse courses

    Multiple type parameters

    Templates can take more than one type, just like std::map<Key, Value>.

    template <typename A, typename B>
    struct Pair {
        A first;
        B second;
    };
    
    Pair<std::string, int> score{"Asha", 95};
    

    What templates require of a type

    A template silently assumes the type supports whatever operations the body uses. largest uses >, so it works for any type with a > operator and fails to compile for types without one. The error appears only when you instantiate the template with an unsuitable type — one reason template errors can look long. C++20 concepts let you state these requirements up front for clearer messages:

    #include <concepts>
    
    // only accept types that can be compared with >
    template <typename T>
        requires std::totally_ordered<T>
    T largest(const T& a, const T& b) {
        return (a > b) ? a : b;
    }
    

    Now calling largest with a type that cannot be ordered produces a short, readable error ("constraint not satisfied") instead of a wall of template-instantiation noise. Concepts make generic code both safer and self-documenting.

    Common mistakes

    • Splitting template definitions across .cpp files. Templates are usually fully defined in headers, because the compiler needs the full definition at every instantiation point. Splitting the body into a separate .cpp file commonly causes "undefined reference" link errors.
    • Assuming a type supports an operation it does not. largest on a type without > fails at instantiation, not at the template's definition.
    • Forgetting the angle brackets for class templates. Write Box<int>, not just Box, when naming the type.
    • Over-templatising. If a function will only ever take an int, a template adds complexity for no benefit. Use templates where genuine type-generality pays off.

    FAQ

    What is the difference between a function template and a class template? A function template generates functions for different types (the compiler usually deduces the type from arguments). A class template generates whole classes for different types, and you usually name the type explicitly, as in std::vector<int>.

    Are templates slower than normal code? No. Templates are resolved at compile time and produce ordinary, fully optimised code for each type — there is no run-time cost like a virtual call.

    Keep learning

    Go from basics to generic programming with mentors in Jalgaon — join the waitlist for our C++ Programming course.

    Want to learn this properly?

    Join the waitlist for our courses — beginner-friendly, project-first classes in Jalgaon.

    Browse courses
    Atul Kabra

    Founder, Infoplanet

    Atul Kabra founded Infoplanet in 2001 and has spent over two decades teaching programming — C, C++, Java, databases and more — to students across Maharashtra.

    Related guides