Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/VrajPatel105/cpp-gpu-inference/llms.txt

Use this file to discover all available pages before exploring further.

The C++ Standard Template Library (STL) provides production-grade implementations of the data structures and algorithms that appear repeatedly in ML systems code. std::vector replaces manually managed dynamic arrays, std::unordered_map provides O(1) average-case key-value lookup, and the <algorithm> header delivers sorting, filtering, and counting without writing any loops by hand. Lambdas tie these together by letting you define short comparison or predicate functions inline, exactly where they are used. The stl.cpp module in this project exercises all four in a single cohesive task: read ten integers, sort descending, count evens, and build a frequency map.

std::vector: Dynamic Contiguous Arrays

std::vector<T> is a heap-allocated array that grows automatically. Elements are stored contiguously in memory, so indexing is O(1) and cache performance matches a plain C array.
#include <iostream>
#include <vector>
using namespace std;

int main(){
    vector<int> user_input;

    // append elements one at a time
    for(int i = 0; i < 10; i++){
        int current_user_input;
        cin >> current_user_input;
        user_input.push_back(current_user_input);
    }

    // index-based access
    for(int i = 0; i < user_input.size(); i++){
        cout << user_input[i] << endl;
    }
}

push_back

Appends an element to the end. Amortized O(1) — the vector occasionally reallocates to a larger buffer, but not on every call.

reserve(n)

Pre-allocates capacity for n elements without changing size. Use this before filling a vector in a loop to avoid repeated reallocations.

std::unordered_map: Hash Map Lookup

std::unordered_map<K, V> stores key-value pairs with O(1) average-case insert and lookup. The mpp[key]++ idiom is idiomatic for building frequency tables: if the key does not exist, it is default-constructed (to 0 for int) before being incremented.
#include <unordered_map>
using namespace std;

// build a frequency map from a sorted vector
unordered_map<int, int> mpp;
for(auto &it : user_input){
    mpp[it]++;    // default-inserts 0 if key absent, then increments
}

// iterate over key-value pairs
for(auto &pair : mpp){
    cout << pair.first << " -> " << pair.second << endl;
}
unordered_map iteration order is unspecified — the pairs come back in hash bucket order, not insertion order. Use std::map (a red-black tree) if sorted iteration is required, at the cost of O(log n) operations.

<algorithm>: Sort and Count

The <algorithm> header provides generic algorithms that operate on iterator ranges. Passing begin() and end() of a vector covers the entire container.

Sorting with a Lambda Comparator

std::sort accepts an optional third argument: a binary comparator that returns true if the first argument should come before the second. A lambda defined inline avoids the need for a separate named function.
#include <algorithm>
using namespace std;

// sort descending — larger values come first
sort(user_input.begin(), user_input.end(), [](int a, int b){
    return a > b;
});

Counting with a Predicate

std::count_if counts elements that satisfy a predicate lambda:
// count how many elements are even
int even_num_count = count_if(
    user_input.begin(),
    user_input.end(),
    [](int num){ return num % 2 == 0; }
);
printf("Total even number count : %d", even_num_count);

Lambdas

A lambda is an anonymous function object defined inline. The general syntax is:
[capture](parameters) -> return_type { body }
The return type can almost always be omitted — the compiler deduces it.
// captures nothing, takes two ints, returns bool
sort(v.begin(), v.end(), [](int a, int b){ return a > b; });

The Full STL Task in One Program

The stl.cpp module chains all four tools together:
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
using namespace std;

class Helper {
public:
    void PrintVec(vector<int> v){
        for(int i = 0; i < v.size(); i++){
            cout << v[i] << endl;
        }
    }
};

int main(){
    Helper h;

    // 1. Read 10 integers into a vector
    vector<int> user_input;
    for(int i = 0; i < 10; i++){
        int current_user_input;
        cin >> current_user_input;
        user_input.push_back(current_user_input);
    }
    h.PrintVec(user_input);

    // 2. Sort descending with a lambda comparator
    sort(user_input.begin(), user_input.end(), [](int a, int b){ return a > b; });
    h.PrintVec(user_input);

    // 3. Count evens with count_if
    int even_num_count = count_if(
        user_input.begin(), user_input.end(),
        [](int num){ return num % 2 == 0; });
    printf("Total even number count : %d", even_num_count);

    // 4 & 5. Build and print a frequency map
    unordered_map<int, int> mpp;
    for(auto &it : user_input){
        mpp[it]++;
    }
    for(auto &pair : mpp){
        cout << pair.first << " -> " << pair.second << endl;
    }

    return 0;
}

Compile and Run

g++ -std=c++20 stl.cpp -o stl
./stl
# Enter 10 integers at the prompt, one per line or space-separated
In CPU-side ML code, vector<float> is the standard container for a matrix row or a 1-D activation buffer. reserve(n) the capacity up front before filling it in a loop to avoid repeated heap reallocations. unordered_map<string, int> is the natural choice for a token-to-ID vocabulary lookup table — O(1) average lookup for millions of tokens.

Build docs developers (and LLMs) love