Project 11.11 Section 11 ⚡ Embedded Relevance: Medium STL Containers Container Selection Performance

11.11 Container Selection Trade-Offs in Embedded Design

Executive Summary: Hands-on challenge manipulating STL containers, demonstrating selection guidelines based on insertion patterns, search frequencies, and memory limits.

💻 1. Annotated Source Code

#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>
#include <string>
#include <algorithm>
using namespace std;

void printVector(const vector<string>& vec);

int main() {

	vector <string> words;

	words.push_back("hi");
	words.emplace_back("hello");
	words.push_back("cat");
	words.emplace_back("world");
	words.push_back("test");

	cout << "Original vector:" << endl;
	printVector(words);

	for (auto it = words.begin(); it != words.end();) {
		if (it->length() <= 3) {
			it = words.erase(it);
		}
		else {
			++it;
		}
	}//end for

	cout << "\nAfter removing short strings (length <= 3):" << endl;
	printVector(words);

	words.erase(remove(words.begin(), words.end(), "test"), words.end());

	cout << "\nAfter removing 'test' using remove-erase idiom:" << endl;
	printVector(words);

	map<string, int> wordLengthsOrdered;
	unordered_map<string, int> wordLengthsUnordered;

	for (const auto& word : words) {
		wordLengthsOrdered[word] = word.length();
		wordLengthsUnordered[word] = word.length();
	}

	cout << "\nContents of map (ordered):" << endl;
	
	for (const auto& pair : wordLengthsOrdered) {
		cout << pair.first << " -> " << pair.second << endl;
	}

	//lookup
	string query = "world";
	cout << "\nLooking up '" << query << "' in both maps:" << endl;

	if (wordLengthsOrdered.find(query) != wordLengthsOrdered.end()) {
		cout << "map: found -> " << wordLengthsOrdered[query] << endl;
	}
	else {
		cout << "map: not found" << endl;
	}

	//unordered map lookup
	if(wordLengthsUnordered.find(query) != wordLengthsUnordered.end()) {
		cout << "unordered map: found -> " << wordLengthsUnordered[query] << endl;
	}
	else {
		cout << "unordered map: not found" << endl;
	}


	return 0;
}

void printVector(const vector<string>& vec) {
	for (const auto& item : vec) {
		cout << item << " ";
	}
	cout << endl;
}

📐 2. Architecture & UML Class Model

📐 Complex STL Functors & Lambda Expression Pipelines
+ Public - Private # Protected
<<compilation-unit>> AdvancedStlPipeline Pipeline Controller
-dataStore : std::map<std::string, std::vector<int32_t>>
+computeAggregates() : void
+filterData(pred: std::function<bool(int)>) : void

📚 3. Core C++ Concepts Deep-Dive

Container Selection Rules

Select containers based on algorithmic complexity and memory topology.

⚡ 4. Embedded Systems & Hardware Reality

Embedded Guidelines

Default to contiguous containers unless non-relocating element requirements mandate node containers.

💡 5. Production-Ready Embedded Refactoring

💡 Production-Ready Refactor
// Always prefer contiguous bounded memory
#include <array>
std::array<int, 10> fixedContainer;

📝 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. Which container should be the default choice for sequential collections in modern C++?
A std::list
B std::vector (or std::array if size is fixed)
C std::deque
D std::forward_list
Detailed Explanation: std::vector and std::array provide optimal cache performance and lowest per-element overhead.