cpp

examples

examples.cpp⚙️
/**
 * Inline Functions and Lambda Expressions - Comprehensive Examples
 * 
 * Demonstrates:
 * - Inline functions
 * - Lambda expressions
 * - Capture modes
 * - Generic lambdas
 * - Lambdas with STL algorithms
 * - std::function
 * 
 * Compile: g++ -std=c++17 -Wall -Wextra examples.cpp -o examples
 * Run: ./examples
 */

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <numeric>
#include <memory>
#include <cmath>      // ⚠️ LEARNING NOTE: Added! sqrt() needs this header

using namespace std;

// ============================================================
// SECTION 1: INLINE FUNCTIONS
// ============================================================

/**
 * Simple inline function - hint to compiler
 */
inline int square(int x) {
    return x * x;
}

inline int cube(int x) {
    return x * x * x;
}

/**
 * Inline max function
 */
inline int maxOf(int a, int b) {
    return (a > b) ? a : b;
}

/**
 * Inline with multiple statements
 */
inline int clamp(int value, int low, int high) {
    if (value < low) return low;
    if (value > high) return high;
    return value;
}

/**
 * constexpr - compile-time inline
 */
constexpr int factorial(int n) {
    return n <= 1 ? 1 : n * factorial(n - 1);
}

constexpr double PI = 3.14159265359;

constexpr double circleArea(double radius) {
    return PI * radius * radius;
}

/**
 * Class with inline member functions
 */
class Point {
private:
    double x_, y_;
    
public:
    Point(double x = 0, double y = 0) : x_(x), y_(y) {}
    
    // Implicitly inline (defined in class)
    double getX() const { return x_; }
    double getY() const { return y_; }
    
    void setX(double x) { x_ = x; }
    void setY(double y) { y_ = y; }
    
    double distanceFromOrigin() const {
        return sqrt(x_ * x_ + y_ * y_);
    }
};

// ============================================================
// SECTION 2: BASIC LAMBDAS
// ============================================================

void demonstrateBasicLambdas() {
    // Simplest lambda - no captures, no params
    auto sayHello = []() {
        cout << "Hello from lambda!" << endl;
    };
    sayHello();
    
    // Lambda with parameters
    auto add = [](int a, int b) {
        return a + b;
    };
    cout << "add(3, 4) = " << add(3, 4) << endl;
    
    // Lambda with explicit return type
    auto divide = [](int a, int b) -> double {
        return static_cast<double>(a) / b;
    };
    cout << "divide(5, 2) = " << divide(5, 2) << endl;
    
    // Immediately invoked lambda
    int result = [](int x) { return x * x; }(5);
    cout << "Immediately invoked: " << result << endl;
    
    // Multi-statement lambda
    auto printRange = [](int start, int end) {
        cout << "Range: ";
        for (int i = start; i <= end; i++) {
            cout << i << " ";
        }
        cout << endl;
    };
    printRange(1, 5);
}

// ============================================================
// SECTION 3: LAMBDA CAPTURES
// ============================================================

void demonstrateCaptureByValue() {
    int x = 10;
    int y = 20;
    
    // Capture x by value (copy)
    auto f1 = [x]() {
        return x * 2;  // Uses copy of x
    };
    cout << "Capture by value: " << f1() << endl;
    
    // Original x unchanged even if we could modify (can't without mutable)
    x = 100;
    cout << "After x=100, lambda still sees: " << f1() << " (captured value)" << endl;
}

void demonstrateCaptureByReference() {
    int counter = 0;
    
    // Capture by reference
    auto increment = [&counter]() {
        counter++;
    };
    
    cout << "Counter before: " << counter << endl;
    increment();
    increment();
    increment();
    cout << "Counter after 3 increments: " << counter << endl;
}

void demonstrateMutableLambda() {
    int value = 10;
    
    // mutable allows modifying the captured copy
    auto modifier = [value]() mutable {
        value++;  // Modifies the copy
        return value;
    };
    
    cout << "First call: " << modifier() << endl;   // 11
    cout << "Second call: " << modifier() << endl;  // 12
    cout << "Original value: " << value << endl;    // Still 10!
}

void demonstrateMixedCaptures() {
    int a = 1, b = 2, c = 3;
    
    // Capture all by value
    auto f1 = [=]() {
        return a + b + c;
    };
    cout << "[=] capture: " << f1() << endl;
    
    // Capture all by reference
    auto f2 = [&]() {
        a++; b++; c++;
    };
    f2();
    cout << "After [&] modify: a=" << a << ", b=" << b << ", c=" << c << endl;
    
    // Mixed: all by value except c by reference
    auto f3 = [=, &c]() {
        c = a + b;
    };
    f3();
    cout << "After [=, &c]: c=" << c << endl;
}

void demonstrateInitCapture() {
    // C++14 init capture (generalized lambda capture)
    
    // Create new variable in capture
    int x = 5, y = 10;
    auto sum = [total = x + y]() {
        return total;
    };
    cout << "Init capture (total = x + y): " << sum() << endl;
    
    // Move into lambda
    auto ptr = make_unique<int>(42);
    auto lambda = [p = move(ptr)]() {
        return *p;
    };
    cout << "Moved unique_ptr value: " << lambda() << endl;
    // ptr is now nullptr
}

// ============================================================
// SECTION 4: GENERIC LAMBDAS (C++14)
// ============================================================

void demonstrateGenericLambdas() {
    // auto parameters make it a template
    auto print = [](const auto& value) {
        cout << value << endl;
    };
    
    print(42);
    print(3.14);
    print("Hello");
    print(string("World"));
    
    // Generic add
    auto add = [](auto a, auto b) {
        return a + b;
    };
    
    cout << "add(1, 2) = " << add(1, 2) << endl;
    cout << "add(1.5, 2.5) = " << add(1.5, 2.5) << endl;
    cout << "add(\"Hello \", \"World\") = " << add(string("Hello "), string("World")) << endl;
    
    // Generic with multiple auto
    auto printPair = [](auto first, auto second) {
        cout << "(" << first << ", " << second << ")" << endl;
    };
    printPair(1, "one");
    printPair(3.14, 'x');
}

// ============================================================
// SECTION 5: LAMBDAS WITH STL ALGORITHMS
// ============================================================

void demonstrateSorting() {
    vector<int> nums = {5, 2, 8, 1, 9, 3, 7};
    
    cout << "Original: ";
    for (int n : nums) cout << n << " ";
    cout << endl;
    
    // Sort descending
    sort(nums.begin(), nums.end(), [](int a, int b) {
        return a > b;
    });
    
    cout << "Descending: ";
    for (int n : nums) cout << n << " ";
    cout << endl;
    
    // Sort by absolute value
    vector<int> mixed = {-5, 3, -1, 4, -2};
    sort(mixed.begin(), mixed.end(), [](int a, int b) {
        return abs(a) < abs(b);
    });
    
    cout << "By absolute value: ";
    for (int n : mixed) cout << n << " ";
    cout << endl;
    
    // Sort strings by length
    vector<string> words = {"apple", "pie", "blueberry", "a", "banana"};
    sort(words.begin(), words.end(), [](const string& a, const string& b) {
        return a.length() < b.length();
    });
    
    cout << "By length: ";
    for (const string& s : words) cout << s << " ";
    cout << endl;
}

void demonstrateFindingAndCounting() {
    vector<int> nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    
    // Find first even
    auto it = find_if(nums.begin(), nums.end(), [](int n) {
        return n % 2 == 0;
    });
    if (it != nums.end()) {
        cout << "First even: " << *it << endl;
    }
    
    // Find first > 5
    it = find_if(nums.begin(), nums.end(), [](int n) {
        return n > 5;
    });
    if (it != nums.end()) {
        cout << "First > 5: " << *it << endl;
    }
    
    // Count evens
    int evenCount = count_if(nums.begin(), nums.end(), [](int n) {
        return n % 2 == 0;
    });
    cout << "Even count: " << evenCount << endl;
    
    // All/any/none checks
    bool allPositive = all_of(nums.begin(), nums.end(), [](int n) { return n > 0; });
    bool anyGreaterThan5 = any_of(nums.begin(), nums.end(), [](int n) { return n > 5; });
    bool noneNegative = none_of(nums.begin(), nums.end(), [](int n) { return n < 0; });
    
    cout << boolalpha;
    cout << "All positive: " << allPositive << endl;
    cout << "Any > 5: " << anyGreaterThan5 << endl;
    cout << "None negative: " << noneNegative << endl;
}

void demonstrateTransforming() {
    vector<int> nums = {1, 2, 3, 4, 5};
    
    // Transform to squares
    vector<int> squares;
    transform(nums.begin(), nums.end(), back_inserter(squares), [](int n) {
        return n * n;
    });
    
    cout << "Squares: ";
    for (int n : squares) cout << n << " ";
    cout << endl;
    
    // Transform in place
    vector<int> values = {1, 2, 3, 4, 5};
    transform(values.begin(), values.end(), values.begin(), [](int n) {
        return n * 2;
    });
    
    cout << "Doubled: ";
    for (int n : values) cout << n << " ";
    cout << endl;
    
    // Accumulate with lambda
    vector<int> data = {1, 2, 3, 4, 5};
    int product = accumulate(data.begin(), data.end(), 1, [](int a, int b) {
        return a * b;
    });
    cout << "Product: " << product << endl;
}

void demonstrateFiltering() {
    vector<int> nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    
    // Remove odd numbers (erase-remove idiom)
    nums.erase(
        remove_if(nums.begin(), nums.end(), [](int n) {
            return n % 2 != 0;  // Remove if odd
        }),
        nums.end()
    );
    
    cout << "After removing odds: ";
    for (int n : nums) cout << n << " ";
    cout << endl;
    
    // Partition: evens first, then odds
    vector<int> data = {1, 2, 3, 4, 5, 6, 7, 8};
    partition(data.begin(), data.end(), [](int n) {
        return n % 2 == 0;
    });
    
    cout << "Partitioned (evens first): ";
    for (int n : data) cout << n << " ";
    cout << endl;
}

void demonstrateForEach() {
    vector<int> nums = {1, 2, 3, 4, 5};
    
    cout << "for_each print: ";
    for_each(nums.begin(), nums.end(), [](int n) {
        cout << n << " ";
    });
    cout << endl;
    
    // Modify in place
    for_each(nums.begin(), nums.end(), [](int& n) {
        n *= 2;
    });
    
    cout << "After doubling: ";
    for (int n : nums) cout << n << " ";
    cout << endl;
    
    // With capture - accumulate into external variable
    int sum = 0;
    for_each(nums.begin(), nums.end(), [&sum](int n) {
        sum += n;
    });
    cout << "Sum: " << sum << endl;
}

// ============================================================
// SECTION 6: std::function
// ============================================================

// Function that accepts any callable
void applyToVector(vector<int>& v, function<int(int)> func) {
    for (int& n : v) {
        n = func(n);
    }
}

// Regular function
int tripleValue(int x) {
    return x * 3;
}

// Functor (function object)
struct Multiplier {
    int factor;
    Multiplier(int f) : factor(f) {}
    int operator()(int x) const {
        return x * factor;
    }
};

void demonstrateStdFunction() {
    cout << "\n--- std::function demonstration ---" << endl;
    
    // Store lambda
    function<int(int, int)> operation = [](int a, int b) { return a + b; };
    cout << "Lambda add: " << operation(3, 4) << endl;
    
    // Reassign to different operation
    operation = [](int a, int b) { return a * b; };
    cout << "Lambda multiply: " << operation(3, 4) << endl;
    
    // Use with regular function
    vector<int> nums = {1, 2, 3};
    applyToVector(nums, tripleValue);
    cout << "After tripleValue: ";
    for (int n : nums) cout << n << " ";
    cout << endl;
    
    // Use with lambda
    nums = {1, 2, 3};
    applyToVector(nums, [](int x) { return x * x; });
    cout << "After square lambda: ";
    for (int n : nums) cout << n << " ";
    cout << endl;
    
    // Use with functor
    nums = {1, 2, 3};
    applyToVector(nums, Multiplier(5));
    cout << "After Multiplier(5): ";
    for (int n : nums) cout << n << " ";
    cout << endl;
    
    // Storing callbacks
    vector<function<void()>> callbacks;
    callbacks.push_back([]() { cout << "Callback 1" << endl; });
    callbacks.push_back([]() { cout << "Callback 2" << endl; });
    callbacks.push_back([]() { cout << "Callback 3" << endl; });
    
    cout << "Executing callbacks:" << endl;
    for (auto& cb : callbacks) {
        cb();
    }
}

// ============================================================
// SECTION 7: ADVANCED LAMBDA PATTERNS
// ============================================================

void demonstrateAdvancedPatterns() {
    cout << "\n--- Advanced Lambda Patterns ---" << endl;
    
    // Lambda returning lambda
    auto makeMultiplier = [](int factor) {
        return [factor](int x) { return x * factor; };
    };
    
    auto times2 = makeMultiplier(2);
    auto times5 = makeMultiplier(5);
    
    cout << "times2(7) = " << times2(7) << endl;
    cout << "times5(7) = " << times5(7) << endl;
    
    // Recursive lambda (requires std::function or Y-combinator)
    function<int(int)> fib = [&fib](int n) -> int {
        if (n <= 1) return n;
        return fib(n - 1) + fib(n - 2);
    };
    cout << "fib(10) = " << fib(10) << endl;
    
    // Lambda with state (counter)
    auto counter = [count = 0]() mutable {
        return ++count;
    };
    cout << "Counter: " << counter() << ", " << counter() << ", " << counter() << endl;
    
    // Compose lambdas
    auto compose = [](auto f, auto g) {
        return [=](auto x) { return f(g(x)); };
    };
    
    auto addOne = [](int x) { return x + 1; };
    auto square = [](int x) { return x * x; };
    auto addOneThenSquare = compose(square, addOne);
    
    cout << "addOneThenSquare(4) = " << addOneThenSquare(4) << " (should be 25)" << endl;
}

// ============================================================
// DEMONSTRATION RUNNER
// ============================================================

void demonstrateInlineFunctions() {
    cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
    cout << "║              SECTION 1: Inline Functions                     ║" << endl;
    cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
    
    cout << "square(5) = " << square(5) << endl;
    cout << "cube(3) = " << cube(3) << endl;
    cout << "maxOf(10, 20) = " << maxOf(10, 20) << endl;
    cout << "clamp(15, 0, 10) = " << clamp(15, 0, 10) << endl;
    
    cout << "\nConstexpr (compile-time):" << endl;
    cout << "factorial(5) = " << factorial(5) << endl;
    cout << "circleArea(3) = " << circleArea(3) << endl;
    
    // Compile-time array size
    constexpr int size = factorial(4);
    int arr[size];  // Array of 24 elements
    cout << "Array size (constexpr): " << size << endl;
    
    Point p(3, 4);
    cout << "\nPoint methods: x=" << p.getX() << ", y=" << p.getY();
    cout << ", distance=" << p.distanceFromOrigin() << endl;
}

void demonstrateLambdaCaptureSection() {
    cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
    cout << "║              SECTION 3: Lambda Captures                      ║" << endl;
    cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
    
    cout << "\n--- Capture by Value ---" << endl;
    demonstrateCaptureByValue();
    
    cout << "\n--- Capture by Reference ---" << endl;
    demonstrateCaptureByReference();
    
    cout << "\n--- Mutable Lambda ---" << endl;
    demonstrateMutableLambda();
    
    cout << "\n--- Mixed Captures ---" << endl;
    demonstrateMixedCaptures();
    
    cout << "\n--- Init Capture (C++14) ---" << endl;
    demonstrateInitCapture();
}

void demonstrateSTLSection() {
    cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
    cout << "║              SECTION 5: Lambdas with STL                     ║" << endl;
    cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
    
    cout << "\n--- Sorting ---" << endl;
    demonstrateSorting();
    
    cout << "\n--- Finding and Counting ---" << endl;
    demonstrateFindingAndCounting();
    
    cout << "\n--- Transforming ---" << endl;
    demonstrateTransforming();
    
    cout << "\n--- Filtering ---" << endl;
    demonstrateFiltering();
    
    cout << "\n--- for_each ---" << endl;
    demonstrateForEach();
}

// ============================================================
// MAIN FUNCTION
// ============================================================

int main() {
    cout << "╔════════════════════════════════════════════════════════════════════╗" << endl;
    cout << "║          C++ INLINE FUNCTIONS AND LAMBDA EXAMPLES                  ║" << endl;
    cout << "║                 Modern C++ Functional Features                     ║" << endl;
    cout << "╚════════════════════════════════════════════════════════════════════╝" << endl;
    
    demonstrateInlineFunctions();
    
    cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
    cout << "║              SECTION 2: Basic Lambdas                        ║" << endl;
    cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
    demonstrateBasicLambdas();
    
    demonstrateLambdaCaptureSection();
    
    cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
    cout << "║              SECTION 4: Generic Lambdas                      ║" << endl;
    cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
    demonstrateGenericLambdas();
    
    demonstrateSTLSection();
    
    cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
    cout << "║              SECTION 6: std::function                        ║" << endl;
    cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
    demonstrateStdFunction();
    
    demonstrateAdvancedPatterns();
    
    cout << "\n╔════════════════════════════════════════════════════════════════════╗" << endl;
    cout << "║                       Examples Complete!                           ║" << endl;
    cout << "╚════════════════════════════════════════════════════════════════════╝" << endl;
    
    return 0;
}
Examples - C++ Tutorial | DeepML