C++ Template Implementation and Usage Patterns

C++ templates enable code reuse by allowing type parametrization—defining logic that operates on unspecified types, which the compiler resolves into concrete implementations based on user-provided type arguments. This eliminates rigid type constraints in statically-typed C++ code.

Compilers do not compile template definitions directly. Instead, they generate type-specific code (instantiation) when a template is used with explicit or deduced type parameters. Different type arguments produce distinct compiled implementations.

Class Templates

Class templates describe families of type-safe, logically related classes distinguished solely by type or value parameters (e.g., integers, pointers/references to global variables). They are ideal for generic data structures.

Syntax and Usage:

#include <iostream>
#include <cmath>
using namespace std;

template <typename U>
class TypeComparer {
public:
    bool isIdentical(U x, U y);
};

template <typename U>
bool TypeComparer<U>::isIdentical(U x, U y) {
    return x == y;
}

// Full specialization for float type
template<>
class TypeComparer<float> {
public:
    bool isIdentical(float x, float y);
};

bool TypeComparer<float>::isIdentical(float x, float y) {
    return abs(x - y) < 1e-3;
}

int main() {
    TypeComparer<int> intComparer;
    cout << intComparer.isIdentical(1, 2) << endl;
    TypeComparer<float> floatComparer;
    cout << floatComparer.isIdentical(1.001f, 1.001f) << endl;
    return 0;
}

Partial Specialization vs Full Specialization

  • Full specialization fixes all type parameters of a class template.
  • Partial specialization fixes only a subset of type parameters, leaving the rest as variables.

Example:

#include <iostream>
using namespace std;

template <typename V, typename W>
class PairWrapper {
public:
    PairWrapper(V val1, W val2) : a(val1), b(val2) {
        cout << "Generic template instantiated" << endl;
    }
private:
    V a;
    W b;
};

// Full specialization for <int, int>
template<>
class PairWrapper<int, int> {
public:
    PairWrapper(int val1, int val2) : a(val1), b(val2) {
        cout << "Full specialization for <int, int>" << endl;
    }
private:
    int a;
    int b;
};

// Partial specialization: first type is fixed to int, second remains variable
template <typename W>
class PairWrapper<int, W> {
public:
    PairWrapper(int val1, W val2) : a(val1), b(val2) {
        cout << "Partial specialization: first type = int" << endl;
    }
private:
    int a;
    W b;
};

int main() {
    PairWrapper<double, double> pw1(1.01, 1.01);
    PairWrapper<int, int> pw2(1, 1);
    PairWrapper<int, const char*> pw3(1, "hello");
    return 0;
}

Function Templates

Function templates define generic functions. Unlike class templates, they support only full specialization; partial specialization is prohibited in standard C++. This limitation is intentional—functon overloading achieves the same flexibility as partial specialization, while avoiding ambiguity in overload resolution.

Function templates and they specializations interact with overload resolution as follows:

  1. Non-template functions take highest priority if parameter types match exactly.
  2. If no matching non-template function exists, the compiler selects the most specialized applicable base template.
  3. If a selected base template has a full specialization for the deduced type, the specialization is used.

Example of Function Template Overload and Specialization:

#include <iostream>
using namespace std;

template <typename T>
void process(T arg) {
    cout << "Generic function: " << arg << endl;
}

template <typename T>
void process(T* arg) {
    cout << "Overloaded pointer version: " << *arg << endl;
}

template<>
void process<int>(int arg) {
    cout << "Full specialization for int: " << arg << endl;
}

void process(double arg) {
    cout << "Non-template double version: " << arg << endl;
}

int main() {
    bool flag = true;
    int num = 42;
    double dbl = 3.14;
    process(flag);       // Calls generic process<bool>
    process(&num);       // Calls pointer overload
    process(num);        // Calls full specialization process<int>
    process(dbl);        // Calls non-template double function
    return 0;
}

Tags: C++ Templates Class Templates Function Templates Specialization

Posted on Wed, 13 May 2026 00:09:31 +0000 by wholetthe15