C++ Standard Library Hidden Gems - 6 Headers You're Probably Overlooking
<numeric> - Not Just Math, Actually Useful
Most beginners never include <numeric>. I didn't either - until I needed to compute a cumulative sum and wrote a 5-line loop. Then someone showed me:
#include <numeric>
#include <vector>
std::vector<int> v = {1, 2, 3, 4, 5};
// Sum all elements - no loop needed
int total = std::accumulate(v.begin(), v.end(), 0); // 15
// Fill with sequential values
std::iota(v.begin(), v.end(), 1); // v = {1, 2, 3, 4, 5} again
// GCD and LCM (C++17)
int g = std::gcd(12, 18); // 6
int l = std::lcm(12, 18); // 36
// Prefix sum - partial_sum produces {1, 3, 6, 10, 15}
std::vector<int> prefix(v.size());
std::partial_sum(v.begin(), v.end(), prefix.begin());
std::accumulate alone has probably saved me 50 lines of boilerplate. std::gcd and std::lcm replaced hand-written Euclidean algorithm functions I had copy-pasted across three projects.
<algorithm> - Beyond sort(), There's Gold
Everyone knows std::sort. But <algorithm> is massive, and some of its best tools are rarely taught:
#include <algorithm>
#include <vector>
std::vector<int> v = {5, 2, 9, 1, 5, 6};
// Find the 3rd smallest element (no full sort needed!)
std::nth_element(v.begin(), v.begin() + 2, v.end());
// v[2] is now the 3rd smallest; elements before are <=, after are >=
// All permutations (great for brute-force problems on Luogu!)
std::string s = "123";
do {
std::cout << s << std::endl; // prints 123, 132, 213, 231, 312, 321
} while (std::next_permutation(s.begin(), s.end()));
// Binary search on sorted ranges
bool found = std::binary_search(v.begin(), v.end(), 5);
// Rotate array elements
std::rotate(v.begin(), v.begin() + 2, v.end());
// {1, 2, 3, 4, 5} -> {3, 4, 5, 1, 2}
std::next_permutation is a cheat code for competitive programming brute-force problems. std::nth_element is O(n) - way faster than sorting the whole array when you only need one element.
<string_view> (C++17) - Avoid Unnecessary Copies
When you pass a string to a function, C++ usually copies it (or you use const std::string& and hope the caller has a std::string). What if the caller has a const char* or a substring?
#include <string_view>
#include <iostream>
// Works with std::string, const char*, and substrings - zero copies!
void print_first_word(std::string_view text) {
auto pos = text.find(' ');
std::cout << text.substr(0, pos) << std::endl;
}
int main() {
std::string s = "hello world";
print_first_word(s); // works
print_first_word("goodbye world"); // works - no allocation!
print_first_word(s.substr(0, 5) + "!"); // works on substring
}
std::string_view is a lightweight, non-owning view into a string. It's essentially a pointer + length. No heap allocation, no copying. For read-only string parameters, there's almost no reason to use const std::string& anymore.
<optional> (C++17) - Functions That Might Fail, Without Exceptions
How do you write a function that "might not have an answer"? Without <optional>, beginners often return sentinel values like -1 or empty strings:
#include <optional>
#include <string>
#include <vector>
// Clean: no sentinel values, no exceptions
std::optional<int> find_index(const std::vector<int>& v, int target) {
for (size_t i = 0; i < v.size(); i++) {
if (v[i] == target) return i;
}
return std::nullopt; // "no answer"
}
// Usage
auto idx = find_index({3, 1, 4, 1, 5}, 4);
if (idx) {
std::cout << "Found at: " << *idx << std::endl; // 2
} else {
std::cout << "Not found" << std::endl;
}
// Or use value_or() for defaults
int position = find_index({3, 1, 4, 1, 5}, 99).value_or(-1); // -1
This replaces the "is this return value valid?" guessing game with a type-safe approach. The compiler forces you to check before using the value.
<bitset> - Bit Manipulation Without Headaches
Bit operations are common in competitive programming (set representation, DP state compression, flags). The manual way with <<, >>, &, | is error-prone:
#include <bitset>
#include <iostream>
// Fixed-size bit array - operations read like English
std::bitset<8> bits("10110011");
std::cout << bits.count() << std::endl; // 5 (number of 1s)
std::cout << bits.test(3) << std::endl; // 0 (bit at position 3)
std::cout << bits.any() << std::endl; // true (at least one 1?)
bits.set(0, true); // set bit 0 to 1
bits.flip(2); // toggle bit 2
bits.reset(7); // set bit 7 to 0
std::cout << bits.to_ullong() << std::endl; // convert to unsigned long long
std::cout << bits.to_string() << std::endl; // back to string "00110011"
std::bitset handles boundary checks and conversion, and the .count() method is internally optimized. For bit DP problems on Luogu, this is a lifesaver.
<tuple> + Structured Bindings (C++17) - Return Multiple Values Cleanly
Returning multiple values from a function used to mean either std::pair (only two values) or std::tuple with verbose std::get<>():
#include <tuple>
#include <iostream>
// Return three values naturally
std::tuple<int, double, std::string> get_stats() {
return {42, 3.14, "hello"};
}
int main() {
// C++17 structured binding - auto unpacking!
auto [count, pi, message] = get_stats();
std::cout << count << ", " << pi << ", " << message << std::endl;
// 42, 3.14, hello
// std::tie for existing variables (works in C++11)
int a;
double b;
std::string c;
std::tie(a, b, c) = get_stats();
}
Structured bindings work with structs, pairs, tuples, and arrays. Combined with std::map::insert (which returns pair<iterator, bool>), this pattern appears everywhere in modern C++.
Quick Reference
| Header | Must-Try |
|---|---|
<numeric> |
accumulate, gcd, iota, partial_sum |
<algorithm> |
next_permutation, nth_element, rotate, binary_search |
<string_view> |
Non-owning string parameter - zero-copy |
<optional> |
value_or(), has_value(), std::nullopt |
<bitset> |
count(), set(), flip(), to_string() |
<tuple> |
Structured bindings: auto [a, b, c] = ... |
None of these are "advanced." They're just standard tools that most tutorials skip over because they'd rather teach you to write a swap function by hand. Next time you find yourself writing a loop for something that feels like it should be built-in - it probably is.
GitHub: https://github.com/Cn-Alanwu
Tags: #cpp #beginners #tutorial #programming #cpp17 #stl
Comments
No comments yet. Start the discussion.