Overview of the C++ Standard Library
Learn the C++ Standard Library, including STL containers, algorithms, iterators, and essential components for modern C++ development.
The C++ Standard Library (including the STL) provides ready-to-use, efficient, and safe building blocks that greatly increase productivity: containers, iterators, algorithms, strings, I/O streams, time utilities, file system, concurrency, and utility types. This article summarizes the most common parts of the library and provides short, working examples as a roadmap.
1) Header Structure and Basic Inclusion
The Standard Library is modular. Including only what you need is important for performance and compilation time.
<vector>,<array>,<list>,<deque><map>,<set>,<unordered_map>,<unordered_set><algorithm>,<numeric>,<iterator>,<ranges>(C++20)<string>,<string_view>,<regex><iostream>,<fstream>,<sstream><chrono>,<filesystem>,<random><memory>(smart pointers),<optional>,<variant>,<any><thread>,<mutex>,<future>,<condition_variable>
Compilation examples:
MSVC: cl /std:c++20 main.cpp
GCC/Clang: g++ -std=c++20 main.cpp -o app
2) Containers
Containers store data, are accessed through iterators, and processed using algorithms.
| Type | Examples | Usage |
|---|---|---|
| Sequential | vector, array, deque, list | vector is the general-purpose choice; array for fixed-size data. |
| Ordered Associative | map, set, multimap | Tree-based; ordered access, O(log n) lookup. |
| Unordered (Hash-based) | unordered_map, unordered_set | Hash table-based; average O(1) lookup. |
| Queues/Stacks | queue, priority_queue, stack | FIFO, LIFO, or priority order processing. |
#include <vector>
#include <unordered_map>
#include <iostream>
using namespace std;
int main() {
vector<int> v; v.reserve(5);
v.emplace_back(3); v.emplace_back(1); v.emplace_back(2);
unordered_map<string,int> freq;
for (int x : v) freq[to_string(x)]++;
cout << "v size=" << v.size() << ", 2 freq=" << freq["2"] << "\n";
}
3) Iterators and Algorithms
Iterators abstract container traversal. <algorithm> provides generic, container-agnostic operations.
#include <vector>
#include <algorithm>
#include <numeric>
#include <iostream>
using namespace std;
int main() {
vector<int> a{5,1,4,2,3};
sort(a.begin(), a.end());
int s = accumulate(a.begin(), a.end(), 0);
auto it = find(a.begin(), a.end(), 4);
if (it != a.end()) *it = 40;
transform(a.begin(), a.end(), a.begin(),
[](int x){ return x + 10; });
for (int x : a) cout << x << ' ';
}
4) C++20 Ranges (Briefly)
Ranges allow chaining algorithms with a “pipeline” syntax (requires C++20 support).
#include <vector>
#include <ranges>
#include <iostream>
using namespace std;
int main() {
vector<int> v{1,2,3,4,5,6};
auto even_times10 = v
| views::filter([](int x){ return x%2==0; })
| views::transform([](int x){ return x*10; });
for (int x : even_times10) cout << x << ' ';
}
5) Strings, string_view, and regex
std::string owns memory; std::string_view provides a non-owning view (be careful with lifetimes).
<regex> enables pattern matching.
#include <string>
#include <string_view>
#include <regex>
#include <iostream>
using namespace std;
bool is_email(string_view s) {
static const regex re(R"((\w+)(\.\w+)*@(\w+)(\.\w+)+)");
return regex_match(s.begin(), s.end(), re);
}
int main() {
string name = "Ada Lovelace";
string_view view = name;
cout << view.substr(0, 3) << "\n";
cout << boolalpha << is_email("dev@example.com") << "\n";
}
6) I/O Streams (iostream, fstream, sstream)
Streams chain easily with operators. fstream handles file I/O, and stringstream parses text.
#include <fstream>
#include <sstream>
#include <iostream>
#include <string>
using namespace std;
int main() {
ofstream out("data.txt");
out << "42, Modern C++\n"; out.close();
ifstream in("data.txt");
string line; getline(in, line);
stringstream ss(line);
int id; char comma; string title;
ss >> id >> comma; getline(ss, title);
cout << "id=" << id << " title=" << title << "\n";
}
7) Time and Duration (chrono)
<chrono> provides time measurement and manipulation utilities.
#include <chrono>
#include <iostream>
using namespace std;
int main() {
using namespace chrono;
auto t0 = steady_clock::now();
for (volatile int i=0;i<1000000;i++) {}
auto t1 = steady_clock::now();
cout << "ms=" << duration_cast<milliseconds>(t1 - t0).count() << "\n";
}
8) Filesystem
Cross-platform file and directory management. In older GCC, -lstdc++fs was required, but not anymore in modern compilers.
#include <filesystem>
#include <iostream>
using namespace std;
namespace fs = std::filesystem;
int main() {
for (const auto& e : fs::directory_iterator(".")) {
cout << e.path().filename().string() << "\n";
}
}
9) Random Numbers (random)
Modern C++ uses Mersenne Twister (mt19937) and distribution classes for random number generation.
#include <random>
#include <iostream>
using namespace std;
int main() {
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<int> dist(1, 6);
for (int i=0;i<5;i++) cout << dist(gen) << ' ';
}
10) Memory and Utility Types
<memory> provides smart pointers (unique_ptr, shared_ptr, weak_ptr).
<optional> handles “value or none”; <variant> is a type-safe union; <any> stores any type (type-erasure).
#include <memory>
#include <optional>
#include <variant>
#include <iostream>
using namespace std;
optional<int> parse_pos_int(int x) { return x>=0 ? optional<int>(x) : nullopt; }
int main() {
auto p = make_unique<int>(42);
cout << *p << "\n";
if (auto v = parse_pos_int(-7)) cout << *v; else cout << "none\n";
variant<int,string> v2 = 10; v2 = string("text");
visit([](auto& t){ cout << t << "\n"; }, v2);
}
11) Concurrency (thread, mutex, future)
Basic multithreading and synchronization primitives.
#include <thread>
#include <mutex>
#include <future>
#include <iostream>
using namespace std;
mutex m; int counter = 0;
void work(int n){
lock_guard<mutex> lk(m);
counter += n;
}
int main() {
thread t1(work, 1), t2(work, 2);
t1.join(); t2.join();
auto fut = async(launch::async, []{ return 40 + 2; });
cout << "counter=" << counter << " answer=" << fut.get() << "\n";
}
12) Numeric Tools (numeric, cmath)
<numeric> provides accumulation and transformation; <cmath> handles math functions.
#include <vector>
#include <numeric>
#include <iostream>
using namespace std;
int main() {
vector<double> x{1.0, 2.0, 3.0};
double avg = accumulate(x.begin(), x.end(), 0.0) / x.size();
cout << "average=" << avg << "\n";
}
13) Quick Reference (When to Use What)
- General-purpose container: vector
- Sorted key-value or range queries: map/set
- Fast key lookup (hash-based): unordered_map/unordered_set
- Stream-like, pipeline processing: ranges (C++20)
- Files and directories: filesystem
- High-resolution timing: chrono
- Safe optional return: optional; multi-type value: variant
14) TL;DR
- STL builds upon the trio: containers + iterators + algorithms.
- vector is the default choice; use map/set for sorted, unordered_* for fast access.
- algorithm/numeric enable generic data transformations; C++20 ranges make it expressive.
- string_view gives non-owning, zero-copy string access (watch object lifetime).
- chrono, filesystem, and random simplify system-level tasks.
- Modern utilities: optional, variant, any, smart pointers.
- For concurrency: thread/mutex/future; design carefully for performance-critical sections.
- All examples compile and run on Visual Studio 2022 and GCC 11+.