cpp

examples

examples.cpp⚙️
/**
 * Advanced Templates - Examples
 * Compile: g++ -std=c++17 -Wall examples.cpp -o examples
 */

#include <iostream>
#include <string>
#include <vector>
#include <type_traits>
using namespace std;

// ============================================================
// SECTION 1: VARIADIC TEMPLATES
// ============================================================

// Base case
void print() { cout << endl; }

// Recursive case
template<typename T, typename... Args>
void print(T first, Args... rest) {
    cout << first;
    if constexpr (sizeof...(rest) > 0) cout << ", ";
    print(rest...);
}

template<typename... Args>
size_t countArgs(Args... args) {
    return sizeof...(args);
}

void demoVariadic() {
    cout << "--- Variadic Templates ---\n" << endl;
    
    cout << "  Print: ";
    print(1, 2.5, "hello", 'x');
    
    cout << "  Count: " << countArgs(1, 2, 3, 4, 5) << " arguments" << endl;
}

// ============================================================
// SECTION 2: FOLD EXPRESSIONS (C++17)
// ============================================================

template<typename... Args>
auto sum(Args... args) {
    return (... + args);
}

template<typename... Args>
auto product(Args... args) {
    return (... * args);
}

template<typename... Args>
bool allTrue(Args... args) {
    return (... && args);
}

template<typename... Args>
bool anyTrue(Args... args) {
    return (... || args);
}

template<typename... Args>
void printAll(Args... args) {
    cout << "  ";
    ((cout << args << " "), ...);
    cout << endl;
}

void demoFold() {
    cout << "\n--- Fold Expressions ---\n" << endl;
    
    cout << "  sum(1,2,3,4,5) = " << sum(1,2,3,4,5) << endl;
    cout << "  product(1,2,3,4) = " << product(1,2,3,4) << endl;
    cout << "  allTrue(true,true,false) = " << boolalpha 
         << allTrue(true,true,false) << endl;
    cout << "  anyTrue(false,false,true) = " 
         << anyTrue(false,false,true) << endl;
    
    cout << "  printAll: ";
    printAll(10, 20, 30);
}

// ============================================================
// SECTION 3: TYPE TRAITS
// ============================================================

template<typename T>
void analyzeType() {
    cout << "  is_integral: " << boolalpha << is_integral_v<T> << endl;
    cout << "  is_floating: " << is_floating_point_v<T> << endl;
    cout << "  is_pointer: " << is_pointer_v<T> << endl;
    cout << "  is_const: " << is_const_v<T> << endl;
}

void demoTypeTraits() {
    cout << "\n--- Type Traits ---\n" << endl;
    
    cout << "  Analyzing int:" << endl;
    analyzeType<int>();
    
    cout << "\n  Analyzing const double*:" << endl;
    analyzeType<const double*>();
    
    // Type modifications
    cout << "\n  Type modifications:" << endl;
    cout << "  same type (int, int): " 
         << is_same_v<int, int> << endl;
    cout << "  same type (int, long): " 
         << is_same_v<int, long> << endl;
}

// ============================================================
// SECTION 4: SFINAE
// ============================================================

// Enable only for integral types
template<typename T, 
         typename enable_if<is_integral_v<T>, int>::type = 0>
string getTypeName(T) {
    return "integral";
}

// Enable only for floating point
template<typename T,
         typename enable_if<is_floating_point_v<T>, int>::type = 0>
string getTypeName(T) {
    return "floating point";
}

// Enable for pointers
template<typename T,
         typename enable_if<is_pointer_v<T>, int>::type = 0>
string getTypeName(T) {
    return "pointer";
}

void demoSFINAE() {
    cout << "\n--- SFINAE ---\n" << endl;
    
    cout << "  42 is: " << getTypeName(42) << endl;
    cout << "  3.14 is: " << getTypeName(3.14) << endl;
    
    int x = 10;
    cout << "  &x is: " << getTypeName(&x) << endl;
}

// ============================================================
// SECTION 5: IF CONSTEXPR
// ============================================================

template<typename T>
auto process(T value) {
    if constexpr (is_integral_v<T>) {
        return value * 2;
    } else if constexpr (is_floating_point_v<T>) {
        return value / 2.0;
    } else {
        return value;
    }
}

template<typename T>
void describeType() {
    if constexpr (is_same_v<T, int>) {
        cout << "  Type is int" << endl;
    } else if constexpr (is_same_v<T, double>) {
        cout << "  Type is double" << endl;
    } else if constexpr (is_same_v<T, string>) {
        cout << "  Type is string" << endl;
    } else {
        cout << "  Type is unknown" << endl;
    }
}

void demoIfConstexpr() {
    cout << "\n--- if constexpr ---\n" << endl;
    
    cout << "  process(10) = " << process(10) << endl;
    cout << "  process(10.0) = " << process(10.0) << endl;
    
    describeType<int>();
    describeType<double>();
    describeType<string>();
    describeType<char>();
}

// ============================================================
// SECTION 6: COMPILE-TIME COMPUTATION
// ============================================================

template<unsigned N>
struct Factorial {
    static constexpr unsigned value = N * Factorial<N-1>::value;
};

template<>
struct Factorial<0> {
    static constexpr unsigned value = 1;
};

template<unsigned N>
struct Fibonacci {
    static constexpr unsigned value = 
        Fibonacci<N-1>::value + Fibonacci<N-2>::value;
};

template<> struct Fibonacci<0> { static constexpr unsigned value = 0; };
template<> struct Fibonacci<1> { static constexpr unsigned value = 1; };

void demoCompileTime() {
    cout << "\n--- Compile-Time Computation ---\n" << endl;
    
    cout << "  Factorial<5> = " << Factorial<5>::value << endl;
    cout << "  Factorial<10> = " << Factorial<10>::value << endl;
    
    cout << "  Fibonacci<10> = " << Fibonacci<10>::value << endl;
    cout << "  Fibonacci<15> = " << Fibonacci<15>::value << endl;
}

// ============================================================
// SECTION 7: ADVANCED VARIADIC
// ============================================================

// Tuple-like structure
template<typename... Ts>
struct TypeList {};

template<typename T, typename... Ts>
struct TypeList<T, Ts...> {
    using Head = T;
    using Tail = TypeList<Ts...>;
    static constexpr size_t size = 1 + sizeof...(Ts);
};

template<>
struct TypeList<> {
    static constexpr size_t size = 0;
};

// Perfect forwarding factory
template<typename T, typename... Args>
T* create(Args&&... args) {
    return new T(forward<Args>(args)...);
}

void demoAdvancedVariadic() {
    cout << "\n--- Advanced Variadic ---\n" << endl;
    
    using MyTypes = TypeList<int, double, string>;
    cout << "  TypeList size: " << MyTypes::size << endl;
    cout << "  Head is int: " << is_same_v<MyTypes::Head, int> << endl;
    
    // Factory
    string* str = create<string>("Hello, World!");
    cout << "  Created string: " << *str << endl;
    delete str;
}

// ============================================================
// MAIN
// ============================================================

int main() {
    cout << "╔══════════════════════════════════════╗" << endl;
    cout << "║   ADVANCED TEMPLATES - EXAMPLES      ║" << endl;
    cout << "╚══════════════════════════════════════╝" << endl;
    
    demoVariadic();
    demoFold();
    demoTypeTraits();
    demoSFINAE();
    demoIfConstexpr();
    demoCompileTime();
    demoAdvancedVariadic();
    
    cout << "\n=== Complete ===" << endl;
    return 0;
}
Examples - C++ Tutorial | DeepML