cpp
Inline Lambda
05_Inline_Lambda⚙️cpp
/**
* ============================================================
* C++ INLINE AND LAMBDA FUNCTIONS
* ============================================================
*
* This file covers:
* - Inline functions
* - Lambda expressions (C++11)
* - Captures in lambdas
* - Generic lambdas (C++14)
* - Practical lambda uses
*
* Compile: g++ -std=c++17 -Wall 01_inline_lambda.cpp -o inline_lambda
* Run: ./inline_lambda
*
* ============================================================
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional> // For std::function
#include <string>
using namespace std;
// ============================================================
// INLINE FUNCTIONS
// ============================================================
/*
* inline: A hint to the compiler to insert function code
* at the call site instead of performing a function call.
*
* Benefits:
* - Eliminates function call overhead
* - Good for small, frequently called functions
*
* Notes:
* - Compiler may ignore the hint
* - Can increase binary size
* - Functions in headers should be inline to avoid multiple definitions
*/
inline int square(int x) {
return x * x;
}
inline int max(int a, int b) {
return (a > b) ? a : b;
}
inline double celsiusToFahrenheit(double c) {
return c * 9.0 / 5.0 + 32.0;
}
// ============================================================
// MAIN FUNCTION
// ============================================================
int main() {
cout << "============================================" << endl;
cout << " C++ INLINE AND LAMBDA FUNCTIONS" << endl;
cout << "============================================" << endl << endl;
// ========================================================
// PART 1: INLINE FUNCTIONS
// ========================================================
cout << "--- PART 1: INLINE FUNCTIONS ---" << endl << endl;
cout << "square(5) = " << square(5) << endl;
cout << "max(10, 20) = " << max(10, 20) << endl;
cout << "100°C = " << celsiusToFahrenheit(100) << "°F" << endl;
// Inline is just a hint - compiler decides
cout << "\nNote: 'inline' is a compiler hint, not a guarantee" << endl;
cout << endl;
// ========================================================
// PART 2: LAMBDA BASICS
// ========================================================
cout << "--- PART 2: LAMBDA BASICS ---" << endl << endl;
/*
* Lambda expression syntax:
* [capture](parameters) -> return_type { body }
*
* - capture: variables from enclosing scope
* - parameters: function parameters
* - return_type: (optional) deduced if not specified
* - body: function body
*/
// Simple lambda
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 = [](double a, double b) -> double {
if (b == 0) return 0;
return a / b;
};
cout << "divide(10, 3) = " << divide(10, 3) << endl;
// Immediately invoked lambda
int result = [](int x) { return x * 2; }(5);
cout << "Immediately invoked: " << result << endl;
cout << endl;
// ========================================================
// PART 3: LAMBDA CAPTURES
// ========================================================
cout << "--- PART 3: LAMBDA CAPTURES ---" << endl << endl;
int x = 10;
int y = 20;
// Capture by value [=] or [x]
auto captureByValue = [x]() {
cout << "Captured x by value: " << x << endl;
// x = 100; // ERROR: can't modify by-value capture
};
captureByValue();
// Capture by reference [&] or [&x]
auto captureByRef = [&x]() {
x = 100; // Can modify!
cout << "Modified x to: " << x << endl;
};
captureByRef();
cout << "x after lambda: " << x << endl;
// Mixed captures
x = 10; // Reset
auto mixedCapture = [x, &y]() {
// x is by value (can't modify)
// y is by reference (can modify)
y = x + 30;
};
mixedCapture();
cout << "y after mixed capture: " << y << endl;
// Capture all by value [=]
auto captureAllValue = [=]() {
cout << "x=" << x << ", y=" << y << endl;
};
captureAllValue();
// Capture all by reference [&]
auto captureAllRef = [&]() {
x = 1000;
y = 2000;
};
captureAllRef();
cout << "After [&]: x=" << x << ", y=" << y << endl;
// mutable keyword (modify by-value captures)
int val = 5;
auto mutableLambda = [val]() mutable {
val++; // OK because of mutable
cout << "Inside lambda: val=" << val << endl;
};
mutableLambda();
cout << "Outside lambda: val=" << val << " (unchanged)" << endl;
cout << endl;
// ========================================================
// PART 4: LAMBDAS WITH STL ALGORITHMS
// ========================================================
cout << "--- PART 4: LAMBDAS WITH STL ---" << endl << endl;
vector<int> numbers = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3};
cout << "Original: ";
for (int n : numbers) cout << n << " ";
cout << endl;
// Sort with custom comparator
sort(numbers.begin(), numbers.end(), [](int a, int b) {
return a > b; // Descending order
});
cout << "Sorted desc: ";
for (int n : numbers) cout << n << " ";
cout << endl;
// for_each
sort(numbers.begin(), numbers.end());
cout << "Doubled: ";
for_each(numbers.begin(), numbers.end(), [](int& n) {
n *= 2;
});
for (int n : numbers) cout << n << " ";
cout << endl;
// find_if
auto it = find_if(numbers.begin(), numbers.end(), [](int n) {
return n > 10;
});
if (it != numbers.end()) {
cout << "First > 10: " << *it << endl;
}
// count_if
int evenCount = count_if(numbers.begin(), numbers.end(), [](int n) {
return n % 2 == 0;
});
cout << "Even count: " << evenCount << endl;
// remove_if
numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
numbers.erase(
remove_if(numbers.begin(), numbers.end(), [](int n) {
return n % 2 == 0; // Remove evens
}),
numbers.end()
);
cout << "After removing evens: ";
for (int n : numbers) cout << n << " ";
cout << endl;
// transform
numbers = {1, 2, 3, 4, 5};
vector<int> squared(numbers.size());
transform(numbers.begin(), numbers.end(), squared.begin(), [](int n) {
return n * n;
});
cout << "Squared: ";
for (int n : squared) cout << n << " ";
cout << endl;
cout << endl;
// ========================================================
// PART 5: GENERIC LAMBDAS (C++14)
// ========================================================
cout << "--- PART 5: GENERIC LAMBDAS (C++14) ---" << endl << endl;
// Generic lambda with auto
auto genericAdd = [](auto a, auto b) {
return a + b;
};
cout << "genericAdd(5, 3) = " << genericAdd(5, 3) << endl;
cout << "genericAdd(3.14, 2.0) = " << genericAdd(3.14, 2.0) << endl;
cout << "genericAdd(\"Hello \", \"World\") = " << genericAdd(string("Hello "), string("World")) << endl;
// Generic print lambda
auto printValue = [](const auto& val) {
cout << "Value: " << val << endl;
};
printValue(42);
printValue(3.14);
printValue("Hello");
cout << endl;
// ========================================================
// PART 6: STORING LAMBDAS
// ========================================================
cout << "--- PART 6: STORING LAMBDAS ---" << endl << endl;
// Using auto (most common)
auto lambda1 = [](int x) { return x * 2; };
// Using std::function (more flexible, slight overhead)
function<int(int)> lambda2 = [](int x) { return x * 3; };
cout << "auto lambda: " << lambda1(5) << endl;
cout << "std::function lambda: " << lambda2(5) << endl;
// Array of lambdas
function<int(int, int)> operations[] = {
[](int a, int b) { return a + b; },
[](int a, int b) { return a - b; },
[](int a, int b) { return a * b; },
[](int a, int b) { return b != 0 ? a / b : 0; }
};
cout << "\nOperations on 10 and 3:" << endl;
cout << "Add: " << operations[0](10, 3) << endl;
cout << "Sub: " << operations[1](10, 3) << endl;
cout << "Mul: " << operations[2](10, 3) << endl;
cout << "Div: " << operations[3](10, 3) << endl;
cout << endl;
// ========================================================
// PART 7: PRACTICAL EXAMPLES
// ========================================================
cout << "--- PART 7: PRACTICAL EXAMPLES ---" << endl << endl;
// Custom sorting of strings by length
vector<string> words = {"apple", "pie", "strawberry", "kiwi"};
sort(words.begin(), words.end(), [](const string& a, const string& b) {
return a.length() < b.length();
});
cout << "Sorted by length: ";
for (const string& w : words) cout << w << " ";
cout << endl;
// Filter and transform in one pass
vector<int> data = {-5, 3, -2, 8, -1, 4};
vector<int> positiveSquared;
for_each(data.begin(), data.end(), [&positiveSquared](int n) {
if (n > 0) {
positiveSquared.push_back(n * n);
}
});
cout << "Positive squared: ";
for (int n : positiveSquared) cout << n << " ";
cout << endl;
// Counter using capture
int counter = 0;
auto incrementAndPrint = [&counter]() {
counter++;
cout << "Counter: " << counter << endl;
};
incrementAndPrint();
incrementAndPrint();
incrementAndPrint();
cout << endl;
// ========================================================
// PART 8: CAPTURE SUMMARY
// ========================================================
cout << "--- PART 8: CAPTURE REFERENCE ---" << endl << endl;
cout << "Capture Syntax:" << endl;
cout << "───────────────────────────────────────" << endl;
cout << "[] - Capture nothing" << endl;
cout << "[x] - Capture x by value" << endl;
cout << "[&x] - Capture x by reference" << endl;
cout << "[=] - Capture all by value" << endl;
cout << "[&] - Capture all by reference" << endl;
cout << "[=, &x] - All by value, x by reference" << endl;
cout << "[&, x] - All by reference, x by value" << endl;
cout << "[this] - Capture 'this' pointer" << endl;
cout << "[*this] - Capture 'this' by value (C++17)" << endl;
cout << endl;
cout << "============================================" << endl;
cout << "INLINE & LAMBDA SUMMARY:" << endl;
cout << "============================================" << endl;
cout << "• inline: compiler hint for expansion" << endl;
cout << "• Lambda: anonymous function objects" << endl;
cout << "• Captures: [=] by value, [&] by ref" << endl;
cout << "• auto works for most lambda storage" << endl;
cout << "• Essential for STL algorithms" << endl;
cout << "============================================" << endl;
return 0;
}
// ============================================================
// EXERCISES:
// ============================================================
/*
* 1. Use a lambda to sort a vector of pairs by the second element
*
* 2. Create a lambda that returns another lambda (closure factory)
*
* 3. Use lambdas with accumulate() to:
* - Sum all elements
* - Find product of all elements
* - Concatenate strings
*
* 4. Create a generic compare lambda that can compare any two
* elements of the same type
*
* 5. Use lambdas to implement a simple callback system
*/