CodeNebula
C++98corebeginner

Templates

C++98 · The Foundation · Compiler flag: -std=c++98

Explanation

Functions that work with any data type via a template parameter.

Real-World Scenario

A generic `max` function for a leaderboard.

Quick Snippet

snippet.cpp
template<typename T> T max(T a, T b) { return a > b ? a : b; }

Full Example

function_templates.cpp
// CodeNebula - C++98 Example: Function Templates
// Compile: g++ -std=c++98 -Wall -Wextra -o example function_templates.cpp

// Function templates allow writing a single function definition that works
// with many types. The compiler generates type-specific code at compile time.
// This example shows template max, swap, print_array, and template specialization.

#include <iostream>
#include <string>
#include <cstring>

// ------------------------------------------------------------------
// Basic function template: myMax
// Works with any type that supports operator<
// ------------------------------------------------------------------
template <typename T>
T myMax(T a, T b) {
    return (a > b) ? a : b;
}

// ------------------------------------------------------------------
// Function template: mySwap
// Swaps two values of the same type using a temporary
// ------------------------------------------------------------------
template <typename T>
void mySwap(T& a, T& b) {
    T temp = a;
    a = b;
    b = temp;
}

// ------------------------------------------------------------------
// Function template with a non-type parameter: printArray
// Prints the contents of an array of known size
// ------------------------------------------------------------------
template <typename T>
void printArray(const T arr[], int size) {
    std::cout << "[ ";
    for (int i = 0; i < size; ++i) {
        std::cout << arr[i];
        if (i < size - 1) {
            std::cout << ", ";
        }
    }
    std::cout << " ]" << std::endl;
}

// ------------------------------------------------------------------
// Template with two different type parameters
// Compares values of different types (both must support comparison)
// ------------------------------------------------------------------
template <typename T, typename U>
bool isEqual(T a, U b) {
    return a == b;
}

// ------------------------------------------------------------------
// Explicit (full) template specialization for const char*
// The generic myMax does pointer comparison; we want string comparison.
// ------------------------------------------------------------------
template <>
const char* myMax<const char*>(const char* a, const char* b) {
    // Compare the actual string contents, not addresses
    return (std::strcmp(a, b) > 0) ? a : b;
}

// ------------------------------------------------------------------
// Function template: clamp a value between lo and hi
// ------------------------------------------------------------------
template <typename T>
T clamp(T value, T lo, T hi) {
    if (value < lo) return lo;
    if (value > hi) return hi;
    return value;
}

int main() {
    std::cout << "=== C++98 Function Templates ===" << std::endl;

    // --- myMax with different types ---
    std::cout << "\n--- myMax ---" << std::endl;
    std::cout << "myMax(3, 7)       = " << myMax(3, 7) << std::endl;
    // Expected: 7
    std::cout << "myMax(3.14, 2.72) = " << myMax(3.14, 2.72) << std::endl;
    // Expected: 3.14
    std::cout << "myMax('a', 'z')   = " << myMax('a', 'z') << std::endl;
    // Expected: z

    // Using the specialization for C-strings
    const char* s1 = "apple";
    const char* s2 = "banana";
    std::cout << "myMax(\"apple\",\"banana\") = "
              << myMax(s1, s2) << std::endl;
    // Expected: banana (lexicographic)

    // Explicit type specification
    std::cout << "myMax<double>(3, 7.5) = " << myMax<double>(3, 7.5) << std::endl;
    // Expected: 7.5

    // --- mySwap ---
    std::cout << "\n--- mySwap ---" << std::endl;
    int x = 10, y = 20;
    std::cout << "Before swap: x=" << x << ", y=" << y << std::endl;
    mySwap(x, y);
    std::cout << "After swap:  x=" << x << ", y=" << y << std::endl;
    // Expected: x=20, y=10

    double p = 1.1, q = 9.9;
    std::cout << "Before swap: p=" << p << ", q=" << q << std::endl;
    mySwap(p, q);
    std::cout << "After swap:  p=" << p << ", q=" << q << std::endl;
    // Expected: p=9.9, q=1.1

    std::string sa = "hello", sb = "world";
    std::cout << "Before swap: sa=" << sa << ", sb=" << sb << std::endl;
    mySwap(sa, sb);
    std::cout << "After swap:  sa=" << sa << ", sb=" << sb << std::endl;
    // Expected: sa=world, sb=hello

    // --- printArray ---
    std::cout << "\n--- printArray ---" << std::endl;
    int ints[] = {10, 20, 30, 40, 50};
    std::cout << "int array:    ";
    printArray(ints, 5);
    // Expected: [ 10, 20, 30, 40, 50 ]

    double dbls[] = {1.1, 2.2, 3.3};
    std::cout << "double array: ";
    printArray(dbls, 3);
    // Expected: [ 1.1, 2.2, 3.3 ]

    // --- isEqual with two types ---
    std::cout << "\n--- isEqual (two type params) ---" << std::endl;
    std::cout << "isEqual(5, 5.0)  = " << (isEqual(5, 5.0) ? "true" : "false") << std::endl;
    // Expected: true
    std::cout << "isEqual(5, 5.1)  = " << (isEqual(5, 5.1) ? "true" : "false") << std::endl;
    // Expected: false

    // --- clamp ---
    std::cout << "\n--- clamp ---" << std::endl;
    std::cout << "clamp(15, 0, 10)   = " << clamp(15, 0, 10) << std::endl;
    // Expected: 10
    std::cout << "clamp(-5, 0, 10)   = " << clamp(-5, 0, 10) << std::endl;
    // Expected: 0
    std::cout << "clamp(5, 0, 10)    = " << clamp(5, 0, 10) << std::endl;
    // Expected: 5
    std::cout << "clamp(3.7, 1.0, 3.5) = " << clamp(3.7, 1.0, 3.5) << std::endl;
    // Expected: 3.5

    return 0;
}

/*
Expected Output:
=== C++98 Function Templates ===

--- myMax ---
myMax(3, 7)       = 7
myMax(3.14, 2.72) = 3.14
myMax('a', 'z')   = z
myMax("apple","banana") = banana
myMax<double>(3, 7.5) = 7.5

--- mySwap ---
Before swap: x=10, y=20
After swap:  x=20, y=10
Before swap: p=1.1, q=9.9
After swap:  p=9.9, q=1.1
Before swap: sa=hello, sb=world
After swap:  sa=world, sb=hello

--- printArray ---
int array:    [ 10, 20, 30, 40, 50 ]
double array: [ 1.1, 2.2, 3.3 ]

--- isEqual (two type params) ---
isEqual(5, 5.0)  = true
isEqual(5, 5.1)  = false

--- clamp ---
clamp(15, 0, 10)   = 10
clamp(-5, 0, 10)   = 0
clamp(5, 0, 10)    = 5
clamp(3.7, 1.0, 3.5) = 3.5
*/
Run command
g++ -std=c++98 -Wall -Wextra -o example function_templates.cpp