Project 11.08 Section 11 ⚡ Embedded Relevance: High <algorithm> std::sort std::count_if Lambdas Zero-Cost Abstractions

11.08 std::sort, std::count_if, and Lambda Inlining vs C qsort Function Pointers

Executive Summary: Exploring the standard algorithm library. We demonstrate why C++ templates and lambdas outperform traditional C qsort() by enabling complete compiler inlining, and examine stack consumption during recursive algorithms.

💻 1. Annotated Source Code

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <algorithm>
using namespace std;

void fillVector(vector<int>& myVector);
void printVector(const vector<int>& myVector);
void countFives(const vector<int>& myVector);

int main() {

	vector<int> myVector;

	fillVector(myVector);
	printVector(myVector);

	countFives(myVector);

	cout << "\nReplacing 5s with 99s" << endl;
	replace(myVector.begin(), myVector.end(), 5, 99);

	countFives(myVector);
	printVector(myVector);

	cout << "\nNow sorting vector..." << endl;
	sort(myVector.begin(), myVector.end());
	printVector(myVector);


	return 0;
}

void fillVector(vector<int>& myVector) {
	srand(time(nullptr));
	for (int i = 0; i < 20; ++i) {
		myVector.push_back(rand() % 5 + 1);  // 1 to 5
	}
}

void printVector(const vector<int>& myVector) {
	for (int value : myVector) {
		cout << value << " ";
	}
}

void countFives(const vector<int>& myVector) {
	int countOfFives = count(myVector.begin(), myVector.end(), 5);
	cout << "Number of 5s: " << countOfFives << endl;
}

📐 2. Architecture & UML Class Model

📐 STL Iterator Algorithms: std::sort, std::find, std::count_if
+ Public - Private # Protected
<<compilation-unit>> StlAlgorithmsEngine Generic Algorithm Pipeline
(none / stateless)
+sort<RandomIt>(first: RandomIt, last: RandomIt) : void[IntroSort]
+find_if<InputIt, Pred>(first: InputIt, last: InputIt, p: Pred) : InputIt
+transform<InputIt, OutputIt, Op>(first: InputIt, last: InputIt, d_first: OutputIt, op: Op) : OutputIt
+count_if<InputIt, Pred>(first: InputIt, last: InputIt, p: Pred) : size_t

📚 3. Core C++ Concepts Deep-Dive

1. Decoupled Iterators and Generic Predicates

STL algorithms in <algorithm> operate uniformly on iterator ranges [begin, end) and accept stateless or capturing lambdas as evaluation predicates.

⚡ 4. Embedded Systems & Hardware Reality

1. Zero-Cost Abstraction: Lambdas vs C Function Pointers

In C, qsort() requires a function pointer callback, forcing an indirect call for every comparison. In C++, std::sort accepts a lambda whose type is known at compile time, allowing the compiler to inline the comparison directly into the sort loop for maximum throughput.

💡 5. Production-Ready Embedded Refactoring

💡 Production-Ready Refactor
#include <algorithm>
#include <array>
#include <iostream>

int main() {
    std::array<int, 5> telemetry = {45, 12, 85, 32, 89};
    
    // Fully inlined at -O2: Zero function pointer overhead
    std::sort(telemetry.begin(), telemetry.end(), [](int a, int b) {
        return a < b;
    });

    for (int val : telemetry) std::cout << val << ' ';
    return 0;
}

📝 Knowledge Verification Quiz

Test your understanding of the C++ concepts and embedded microcontroller trade-offs covered in this guide. Click any option for instant feedback.

Q1. Why is std::sort typically significantly faster than C qsort() on ARM microcontrollers?
A std::sort uses hardware floating-point acceleration.
B std::sort is templated on the comparator type, enabling the compiler to inline comparisons and eliminate indirect function calls.
C qsort() allocates memory on the heap.
D std::sort runs in parallel on all cores.
Detailed Explanation: Because std::sort knows the exact comparator type at compile-time, it inlines the predicate directly, avoiding indirect function pointer jumps.