Free tutorials & notes in Hindi & English · Clean code examples · Mobile friendly learning
📘 Lesson  ·  Lesson 74

STL Overview

Written and reviewed by · Senior IT Faculty · 15+ years’ experience

What Is the C++ STL?

The Standard Template Library (STL) is the generic-programming foundation commonly used to describe the standard library's containers, iterators, algorithms and function objects. These components are designed to cooperate: a container stores values, iterators describe a range, and an algorithm operates on that range without needing to know the container's concrete type.

#include <algorithm>
#include <vector>

std::vector<int> values{5, 2, 9, 2};
std::sort(values.begin(), values.end());

STL is often used informally for the whole C++ standard library, but that is imprecise. Streams, strings, regular expressions, threads and the filesystem are standard-library facilities; the classic STL model is the generic container–iterator–algorithm system.

Core idea: learn the requirements and complexity contracts, then combine tested library components instead of rebuilding lists, sorting and searching by hand.

How the STL Architecture Fits Together

ComponentResponsibilityExamples
ContainerOwns and organizes elementsvector, map, set
IteratorIdentifies a position/rangebegin(), end()
AlgorithmTransforms, searches or measures a rangesort, find_if
CallableCustomizes an algorithmlambda, comparator, predicate
Range (C++20)Packages a begin/end rangestd::ranges::sort
const auto passed = std::count_if(
    marks.begin(), marks.end(),
    [](int mark) { return mark >= 40; }
);

The algorithm accepts an iterator range and a predicate. It does not own the data. This separation makes the same algorithm reusable with many containers whose iterators satisfy its requirements.

Headers matter: <vector> declares vector, <algorithm> declares sorting/search algorithms, and <numeric> declares accumulate. Include what the source directly uses.

Choosing the Right Container

NeedUsually chooseImportant property
General growable sequencevectorContiguous; O(1) indexing; amortized O(1) push-back
Fast insertion at both endsdequeO(1) front/back operations; not one contiguous block
Fixed compile-time sizearrayContiguous; size is part of its type
Frequent splice with stable positionslistNo random access; extra nodes and poor locality
Sorted unique valuessetOrdered; logarithmic search/insert/erase
Sorted key-value recordsmapUnique ordered keys; logarithmic operations
Hash lookup, order unneededunordered_mapAverage O(1), worst O(n); rehash considerations
LIFO/FIFO restricted interfacestack/queueContainer adapters, not general traversal containers

vector is the default sequence because compact contiguous elements exploit caches well. Do not select list merely because insertion is O(1): reaching the position is O(n), allocation is per node, and real workloads often favor vector.

See the focused lessons on vector and set and map.

Iterators, Categories and Half-Open Ranges

An iterator behaves like a generalized position. A range is normally [first, last): it includes first and excludes last. For a complete container, use begin() and end(); end() is a sentinel position and must not be dereferenced.

for (auto it = values.cbegin(); it != values.cend(); ++it) {
    std::cout << *it << ' ';
}
CapabilityTypical sourcePermits
Inputreadable stream/rangesingle-pass reading
Forwardforward_listmulti-pass forward movement
Bidirectionallist, map++ and --
Random accessdequejumps, differences, ordering
Contiguousvector, arrayadjacent storage plus random access

std::sort requires random-access iterators, so it works with vector but not list. A list supplies its own list::sort. Study C++ iterators before keeping them across mutations.

Algorithms in Practice

#include <algorithm>
#include <numeric>
#include <vector>

std::vector<int> data{7, 2, 9, 4};
std::sort(data.begin(), data.end());

auto first_even = std::find_if(data.begin(), data.end(),
                               [](int n) { return n % 2 == 0; });
int total = std::accumulate(data.begin(), data.end(), 0);
std::transform(data.begin(), data.end(), data.begin(),
               [](int n) { return n * 2; });

The initial value in accumulate also helps determine the result type. Use 0LL when summing many integers into long long. A comparator must define a valid strict weak ordering; writing a <= b for sort is wrong.

If a vector is already sorted, lower_bound performs logarithmic comparisons. Calling it on an unsorted range produces no useful search guarantee. C++20 ranges can make intent clearer:

#include <ranges>
std::ranges::sort(data);
auto odds = data | std::views::filter([](int n) { return n % 2; });

Views are often lazy and may refer to another range; manage source lifetimes carefully. Continue with STL algorithms.

Complexity, Allocation and Invalidation

Big-O is a growth contract, not a stopwatch result. O(1) can have a large constant; O(n) over contiguous memory may beat pointer-heavy traversal for practical sizes. Evaluate element size, allocation, hashing, cache locality and the actual input distribution.

  • vector growth: when capacity is exhausted, reallocation moves/copies elements and invalidates all iterators, pointers and references.
  • vector erase: handles at or after the erased position are invalidated.
  • map/set insert: existing iterators and references normally remain valid; erasing an element invalidates handles to that element.
  • unordered rehash: iterators are invalidated by rehash; references/pointers to elements remain valid under the standard rules unless the element is erased.
values.reserve(100);       // capacity changes, size does not
values.push_back(42);      // do not retain stale iterators blindly

for (auto it = values.begin(); it != values.end(); ) {
    if (*it < 0) it = values.erase(it);
    else ++it;
}
Safety rule: after a mutating operation, use the returned iterator or reacquire positions unless the container's documented invalidation guarantee proves the old handle valid.

Complete STL Lab with Verified Output

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <numeric>
#include <vector>

int main() {
    std::vector<int> marks{72, 88, 65, 88, 91};

    const int total = std::accumulate(marks.begin(), marks.end(), 0);
    const auto high = std::count_if(marks.begin(), marks.end(),
                                    [](int m) { return m >= 75; });

    std::sort(marks.begin(), marks.end());
    const auto new_end = std::unique(marks.begin(), marks.end());
    marks.erase(new_end, marks.end());

    std::cout << std::fixed << std::setprecision(1)
              << "Average: " << total / 5.0 << '\n'
              << "At least 75: " << high << "\nUnique: ";
    for (int mark : marks) std::cout << mark << ' ';
}
Average: 80.8 At least 75: 3 Unique: 65 72 88 91

The erase–unique idiom has two stages: unique compacts adjacent duplicates and returns the new logical end; erase removes the leftover tail. Sorting first makes equal values adjacent.

Common Mistakes and 100-Point Checklist

MistakeFaculty correction
Choosing a container by habitWrite access, order and invalidation needs first
Dereferencing end()Treat it as an excluded sentinel
Keeping an iterator after reallocationReacquire it or prove validity
Running binary search on unsorted inputMaintain/verify the required ordering
Expecting unordered iteration orderUse ordered container or sort an extracted view
using namespace std; in a headerUse qualified names; avoid namespace pollution
Missing direct headersInclude every facility used
Unsafe index accessValidate index or use at() where appropriate
  1. State the data and ownership model.
  2. Select a container from operations and guarantees.
  3. Check algorithm iterator requirements.
  4. Check preconditions such as sorting.
  5. Account for invalidation after mutation.
  6. Use a valid comparator/predicate.
  7. Compile with -Wall -Wextra -Wpedantic.
  8. Test empty, one-element, duplicate and large cases.
  9. Measure before performance claims.
  10. Record the required language standard.

Authoritative References

The requirements, complexity terminology and invalidation guidance on this page were checked against the current C++ working draft. For a shorter entry point, open STL introduction.

C++ STL क्या है?

STL generic-programming foundation है: containers data own करते हैं, iterators range बताते हैं और algorithms उस range पर काम करते हैं। Function objects/lambdas behavior customize करते हैं।

std::vector<int> values{5,2,9,2};
std::sort(values.begin(),values.end());

पूरी standard library को STL कहना common लेकिन imprecise है; I/O, threads और filesystem भी library facilities हैं।

Core idea: requirements और complexity contract समझकर tested components combine करें; sorting/list को unnecessarily दोबारा न बनाएं।

STL Architecture

PartकामExamples
ContainerElements store/organizevector, map
IteratorPosition/rangebegin, end
AlgorithmSearch/transformsort, find_if
CallableBehavior customizelambda, comparator
Rangebegin/end packageC++20 ranges
auto passed=std::count_if(marks.begin(),marks.end(),
 [](int m){ return m>=40; });

Algorithm data own नहीं करता। Required headers direct include करें: vector के लिए <vector>, algorithms के लिए <algorithm>, accumulate के लिए <numeric>

सही Container कैसे चुनें?

RequirementChoiceProperty
General sequencevectorContiguous, O(1) index
दोनों endsdequeFast front/back
Fixed sizearrayCompile-time size
Splice/stable positionslistNo random access
Sorted unique valuessetO(log n)
Sorted key-valuemapO(log n)
Hash lookupunordered_mapAverage O(1), worst O(n)

Sequence में vector default रखें। list का insertion O(1) होने पर भी position तक पहुंचना O(n), per-node allocation और weak locality हो सकती है। vector तथा set/map पढ़ें।

Iterators और Half-Open Ranges

Range [first,last) first को include और last को exclude करती है। end() sentinel है, element नहीं; इसे dereference न करें।

for(auto it=values.cbegin();it!=values.cend();++it)
 std::cout<<*it<<' ';

Iterator capabilities input, forward, bidirectional, random-access और contiguous तक बढ़ती हैं। sort को random-access चाहिए; इसलिए vector पर चलेगा, list पर नहीं। List का अपना member sort है। अधिक detail: iterators

Algorithms का Practical प्रयोग

std::sort(data.begin(),data.end());
auto it=std::find_if(data.begin(),data.end(),
 [](int n){return n%2==0;});
long long total=std::accumulate(data.begin(),data.end(),0LL);
std::transform(data.begin(),data.end(),data.begin(),
 [](int n){return n*2;});

lower_bound sorted range पर logarithmic comparisons करता है; unsorted data पर precondition पूरी नहीं। Comparator strict weak ordering दे—a<=b गलत है। C++20 में std::ranges::sort(data) intent साफ कर सकता है; lazy views में source lifetime सुरक्षित रखें। algorithms lesson देखें।

Complexity और Invalidation

Big-O growth contract है, exact seconds नहीं। Allocation, cache locality, hash और element size भी measure करें।

  • vector reallocation सभी iterators/references/pointers invalidate करती है।
  • vector erase, erased position और उसके बाद के handles invalidate करता है।
  • map/set insert existing iterators को normally valid रखता है; erase केवल erased element का handle invalidate करता है।
  • unordered rehash iterators invalidate करता है।
values.reserve(100); // capacity, size नहीं
for(auto it=values.begin();it!=values.end();){
 if(*it<0) it=values.erase(it); else ++it;
}
Mutation के बाद returned iterator use या position reacquire करें, जब तक documented guarantee पुराने handle को valid न सिद्ध करे।

Complete Practical Lab और Output

std::vector<int> marks{72,88,65,88,91};
int total=std::accumulate(marks.begin(),marks.end(),0);
auto high=std::count_if(marks.begin(),marks.end(),
 [](int m){return m>=75;});
std::sort(marks.begin(),marks.end());
auto new_end=std::unique(marks.begin(),marks.end());
marks.erase(new_end,marks.end());
Average: 80.8 At least 75: 3 Unique: 65 72 88 91

पहले total 404 और count 3 निकला। Sort duplicates adjacent करता है; unique logical end देता है और erase leftover tail हटाता है।

Mistakes और 100-Point Checklist

MistakeCorrection
Habit से containerOperations/guarantees लिखें
end dereferenceExcluded sentinel मानें
Stale iteratorReacquire/check rule
Unsorted binary searchOrdering सुनिश्चित करें
unordered में orderOrdered container/sort
Header में using namespaceQualified names
  1. Data/ownership model
  2. Container guarantees
  3. Iterator requirement
  4. Algorithm precondition
  5. Invalidation audit
  6. Valid comparator
  7. Warnings enabled
  8. Edge-case tests
  9. Performance measurement
  10. Language standard recorded

Authoritative संदर्भ

Requirements और complexity current working draft से verified हैं। Beginner sequence के लिए STL introduction खोलें।

अक्सर पूछे जाने वाले प्रश्न (FAQ)

क्या STL पूरी C++ standard library के समान है?
पूरी तरह नहीं। STL नाम सामान्यतः generic containers, iterators, algorithms और related function objects के लिए प्रयोग होता है। I/O, threading और filesystem जैसी facilities भी standard library में हैं, लेकिन वे STL core नहीं हैं।
Beginner को default में कौन-सा container लेना चाहिए?
Growable sequence के लिए std::vector से शुरू करें, जब तक ordering, lookup, insertion या invalidation की measured requirement किसी और container की मांग न करे।
Algorithms [first, last) half-open range क्यों लेते हैं?
first पहला element है और last range के बाद की position। इससे empty range natural बनती है और adjacent ranges एक boundary share कर सकती हैं। last/end को dereference नहीं करना चाहिए।
क्या unordered_map हमेशा O(1) है?
नहीं। Suitable hashing/load में operations average O(1) हो सकते हैं, लेकिन worst case O(n) है और iteration sorted नहीं होती।
Iterator invalidation क्या है?
किसी container operation के बाद पुराना iterator, pointer या reference valid element को identify करना बंद कर सकता है। Exact rule container और operation पर निर्भर है।
← Back to C++ Tutorial
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।