STL Best practices

In this document, we discuss how to effectively code with the C++ Standard Template Library (STL) while maintaining high-quality code. Thus we list some, best practices related to code structure, code safety, and code generality. These practices are key to writing clean, efficient, and maintainable C++ code that leverages the power of STL effectively.


1. Prefer High-Level STL Containers Over Raw Arrays and Pointers

cpp std::vector<int> vec = {1, 2, 3, 4}; // Dynamic array std::array<int, 4> arr = {1, 2, 3, 4}; // Fixed-size array


2. Use Range-Based Loops for Readability

```cpp std::vector words = {"hello", "world"};

for (const auto& word : words) { // const reference avoids copy std::cout << word << std::endl; } ```


3. Use STL Algorithms Instead of Manual Loops

cpp std::vector<int> vec = {4, 2, 3, 1}; std::sort(vec.begin(), vec.end()); // Sort instead of writing a loop

Example with std::transform and Lambda: cpp std::vector<int> nums = {1, 2, 3}; std::transform(nums.begin(), nums.end(), nums.begin(), [](int x) { return x * 2; });


4. Use const Wherever Possible

cpp const int size = 10; // `size` is constant, can’t be changed

cpp void printVector(const std::vector<int>& vec) { // Passed as const reference for (const auto& v : vec) { std::cout << v << std::endl; } }


5. Prefer std::unique_ptr or std::shared_ptr Over Raw Pointers

cpp std::unique_ptr<int> ptr = std::make_unique<int>(42); // Exclusive ownership std::shared_ptr<int> sharedPtr = std::make_shared<int>(42); // Shared ownership


6. Leverage Iterator Categories Appropriately

cpp std::vector<int> vec = {1, 2, 3}; std::sort(vec.begin(), vec.end()); // Works with random-access iterators (vector)


7. Favor emplace_back Over push_back for Efficiency

cpp std::vector<std::pair<int, std::string>> vec; vec.emplace_back(1, "example"); // Constructs in place, avoids copy


8. Understand Container Choice and Complexity Guarantees

```cpp // Example: Prefer vector for simple dynamic arrays std::vector vec = {1, 2, 3}; // Fast access and resizing

// Example: Prefer set when uniqueness and sorting are required std::set mySet = {3, 1, 2}; // Automatically sorted, unique elements ```


9. Avoid Modifying Containers While Iterating Over Them

```cpp std::vector vec = {1, 2, 3, 4, 5};

// Safe way to remove elements during iteration vec.erase(std::remove_if(vec.begin(), vec.end(), { return x % 2 == 0; }), vec.end()); ```


10. Use std::move to Avoid Unnecessary Copies

```cpp std::vector vec; std::string s = "example";

// Move s into the vector, avoiding a copy vec.push_back(std::move(s)); ```


11. Use std::initializer_list for Convenient Initialization

Practices**: - Use initializer lists to simplify container initialization and custom class constructors.

cpp std::vector<int> vec = {1, 2, 3}; // Automatically uses initializer_list


12. Handle Exceptions Correctly


Conclusion:

By following these best practices, your students will develop a solid foundation for writing clean, efficient, and maintainable C++ code using the STL. The focus should be on leveraging STL's powerful abstractions, improving code safety with modern features (like smart pointers and range-based loops), and writing generic, reusable code by using algorithms and iterators effectively.

Previous Page | Course Schedule | Course Content