C++: STL Container Basics

In previous lessons, we learned about templates — making functions and classes support any type.

But in real projects, you don't need to write your own containers (like dynamic arrays or linked lists).

The C++ Standard Template Library (STL) already provides ready-made containers — just use them directly!


1. What Is the STL?

The STL (Standard Template Library) is part of the C++ standard library, containing:

Component Purpose Examples
Containers Store data std::vector, std::array
Iterators Traverse containers begin(), end()
Algorithms Manipulate data std::sort, std::find
Function objects Custom comparison logic std::less, std::greater

💡 Key point: The STL is implemented with templates, so it supports any type.



2. vector (Most Commonly Used)

(1) 2.1 What Is vector?

std::vector is a dynamic array — its size can grow automatically.

Comparison Plain Array vector
Size Fixed Dynamic
Memory Stack or heap Heap
Access elements arr[i] vec[i] or vec.at(i)
Recommendation ⭐⭐ ⭐⭐⭐⭐⭐

▶ Example 1: vector Basic Usage (Difficulty ⭐)

CPP
#include <iostream>
#include <vector>

int main() {
 // Create a vector storing ints
 std::vector<int> vec = {1, 2, 3, 4, 5};
 
 // Access elements
 std::cout << "First element: " << vec[0] << std::endl;
 std::cout << "Second element: " << vec.at(1) << std::endl;
 
 // Modify elements
 vec[0] = 100;
 
 // Get size
 std::cout << "Size: " << vec.size() << std::endl;
 
 return 0;
}
▶ Try it Yourself

Output:

TEXT 📖 Display only
First element: 1
Second element: 2
Size: 5

💡 Tip: vec.at(i) performs bounds checking and throws an exception if out of bounds; vec[i] does not check, and is more efficient.


(2) 2.2 Adding and Removing Elements

CPP
#include <iostream>
#include <vector>

int main() {
 std::vector<int> vec;
 
 // Add elements to the end
 vec.push_back(10);
 vec.push_back(20);
 vec.push_back(30);
 
 // Remove the last element
 vec.pop_back();
 
 // Insert element at a specified position
 vec.insert(vec.begin() + 1, 15); // Insert 15 at the second position
 
 // Remove element at a specified position
 vec.erase(vec.begin() + 1); // Remove the second element
 
 return 0;
}

(3) 2.3 Traversing a vector

Method 1: Subscript traversal (most common)

CPP
#include <iostream>
#include <vector>

int main() {
 std::vector<int> vec = {1, 2, 3, 4, 5};
 
 for (size_t i = 0; i < vec.size(); i++) {
 std::cout << vec[i] << " ";
 }
 std::cout << std::endl;
 
 return 0;
}

Method 2: Range-based for (C++11, recommended)

CPP
#include <iostream>
#include <vector>

int main() {
 std::vector<int> vec = {1, 2, 3, 4, 5};
 
 for (int x : vec) {
 std::cout << x << " ";
 }
 std::cout << std::endl;
 
 return 0;
}

Method 3: Iterators (covered later)

CPP
#include <iostream>
#include <vector>

int main() {
 std::vector<int> vec = {1, 2, 3, 4, 5};
 
 for (auto it = vec.begin(); it != vec.end(); ++it) {
 std::cout << *it << " ";
 }
 std::cout << std::endl;
 
 return 0;
}

💡 Recommendation: Prefer range-based for (C++11) — it's the most concise.



3. array (Fixed-Size Array)

(1) 3.1 What Is array?

std::array is a fixed-size array, but safer than a plain array.

Comparison Plain Array array
Size You need to know it Get with size()
Decays to pointer? Yes No
Recommendation ⭐⭐ ⭐⭐⭐⭐

▶ Example 2: array Basic Usage (Difficulty ⭐)

CPP
#include <iostream>
#include <array>

int main() {
 // Create an array storing 5 ints
 std::array<int, 5> arr = {1, 2, 3, 4, 5};
 
 // Access elements
 std::cout << "First element: " << arr[0] << std::endl;
 
 // Get size
 std::cout << "Size: " << arr.size() << std::endl;
 
 return 0;
}
▶ Try it Yourself

Output:

TEXT 📖 Display only
First element: 1
Size: 5

💡 Key point: The size of std::array is determined at compile time and cannot be changed.



4. deque (Double-Ended Queue)

(1) 4.1 What Is deque?

std::deque is a double-ended queue — you can quickly add/remove elements at both ends.

Operation vector deque
Add at end O(1) O(1)
Add at front O(n) O(1)
Random access O(1) O(1)

▶ Example 3: deque Basic Usage (Difficulty ⭐⭐)

CPP
#include <iostream>
#include <deque>

int main() {
 std::deque<int> dq;
 
 // Add at end
 dq.push_back(10);
 dq.push_back(20);
 
 // Add at front
 dq.push_front(5);
 dq.push_front(1);
 
 // dq is now: 1, 5, 10, 20
 
 for (int x : dq) {
 std::cout << x << " ";
 }
 std::cout << std::endl;
 
 return 0;
}
▶ Try it Yourself

Output:

TEXT 📖 Display only
1 5 10 20


5. list (Doubly Linked List)

(1) 5.1 What Is list?

std::list is a doubly linked list — each element stores the addresses of the previous and next elements.

Comparison vector list
Random access O(1) ❌ Not supported
Insert/delete in middle O(n) O(1)
Memory usage Small Large (two extra pointers per element)

▶ Example 4: list Basic Usage (Difficulty ⭐⭐)

CPP
#include <iostream>
#include <list>

int main() {
 std::list<int> lst = {1, 2, 3, 4, 5};
 
 // Add at front
 lst.push_front(0);
 
 // Add at end
 lst.push_back(6);
 
 // Remove elements with value 3
 lst.remove(3);
 
 for (int x : lst) {
 std::cout << x << " ";
 }
 std::cout << std::endl;
 
 return 0;
}
▶ Try it Yourself

Output:

TEXT 📖 Display only
0 1 2 4 5 6


6. forward_list (Singly Linked List)

(1) 6.1 What Is forward_list?

std::forward_list is a singly linked list — each element only stores the address of the next element.

Comparison list forward_list
Memory usage Larger Smaller
Can traverse backwards?
Recommendation ⭐⭐⭐⭐ ⭐⭐ (for specific scenarios)

💡 Advice: Unless you're certain you only need forward traversal, use std::list.



7. Container Selection Guide

Scenario Recommended Container
Need dynamic size std::vector
Fixed size, want C-style compatibility std::array
Need fast add/remove at front std::deque
Frequent insert/delete in the middle std::list
Only need forward traversal and want to save memory std::forward_list

💡 Golden rule: Prefer std::vector unless you have a clear reason to use something else.



8. Practice: Dynamic Array with vector (Difficulty ⭐⭐)

CPP
#include <iostream>
#include <vector>
#include <string>

struct Student {
 std::string name;
 int age;
 double score;
};

int main() {
 std::vector<Student> students;
 
 // Add students
 students.push_back({"Alice", 20, 92.5});
 students.push_back({"Bob", 21, 88.0});
 students.push_back({"Charlie", 19, 95.0});
 
 // Traverse and output
 for (const auto& s : students) {
 std::cout << "Name: " << s.name 
 << ", Age: " << s.age 
 << ", Score: " << s.score << std::endl;
 }
 
 return 0;
}

❓ FAQ

Q: What's the difference between vector and array? A:> - vector has dynamic size, stored on the heap > - array has fixed size, stored on the stack > > Selection advice: If the size is uncertain, use vector; if the size is fixed and small, use array. Q: Why is range-based for recommended for traversing vector? A: Because it's more concise and less prone to loop condition errors. > > // Traditional for (easy to get conditions wrong) > for (size_t i = 0; i < vec.size(); i++) { ... } > > // Range-based for (concise, less error-prone) > for (int x : vec) { ... } > Q: Which is faster — list or vector? A: It depends on the scenario: > - If you need random access (vec[100]), vector is faster > - If you need frequent insert/delete in the middle, list is faster


Q: What's the most important thing about STL containers? A: Understand the core concepts first, then reinforce them through practical examples.

📖 Summary


📝 Exercises

  1. Basic (Difficulty ⭐): Use std::vector<int> to store 5 integers, traverse and output them.

  2. Intermediate (Difficulty ⭐⭐): Use std::vector<std::string> to store 3 strings, let the user input them, then output.

  3. Challenge (Difficulty ⭐⭐⭐): Use std::deque to implement "palindrome detection":

  4. Compare from both ends toward the middle; if all corresponding characters match, it's a palindrome

  5. Example: "racecar" is a palindrome, "hello" is not


9. 🚀 Next Steps

Now that you've learned STL container basics, next we'll study STL Algorithms (lesson 35) — using the algorithms provided by the standard library to manipulate containers, so you don't have to write your own sorting, searching...

Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏