0% found this document useful (0 votes)
10 views27 pages

STL_notes

The document provides an overview of the Standard Template Library (STL) in C++, focusing on its algorithms and sequence containers such as vectors, lists, and deques. It includes code examples demonstrating various STL functionalities like searching, sorting, merging, and manipulating containers. Additionally, it discusses the advantages of using STL, such as memory management and the use of iterators for efficient data handling.

Uploaded by

aarush289156
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views27 pages

STL_notes

The document provides an overview of the Standard Template Library (STL) in C++, focusing on its algorithms and sequence containers such as vectors, lists, and deques. It includes code examples demonstrating various STL functionalities like searching, sorting, merging, and manipulating containers. Additionally, it discusses the advantages of using STL, such as memory management and the use of iterators for efficient data handling.

Uploaded by

aarush289156
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

OOAIA - Lecture #6

STL

Prashanth L.A. Feb 24, 2026


Agenda

• Standard template library


References

• Chapter 15 of R. Lafore’s book


• Scott Meyers, “E ective STL”
ff
STL Algorithms

• Can operate on traditional arrays, e.g., find, search, sort.


• Q: Why use STL for such operations?
• A: Short/readable code, bug-free, can change to vectors and use iterators
Where is 33?
// nds the rst object with a speci ed value

#include <iostream>

#include <algorithm> //for nd()

using namespace std;

int arr[] = { 11, 22, 33, 44, 55, 66, 77, 88 };

int main()

int* ptr;

ptr = nd(arr, arr+8, 33); // nd rst 33

cout << "First object with value 33 found at offset "

<< (ptr-arr) << endl;

return 0;
}
fi
fi
fi
fi
fi
fi
fi
How many ’33’s?
// counts the number of objects with a speci ed value

#include <iostream>
#include <algorithm> //for count()

using namespace std;

int arr[] = { 33, 22, 33, 44, 33, 55, 66, 77 };

int main()
{

int n = count(arr, arr+8, 33); //count number of 33's

cout << "There are " << n << " 33's in arr." << endl;

return 0;
}
fi
Sorting
// sort an array of integers

#include <iostream>
#include <algorithm>

using namespace std;

// array of numbers
int arr[] = {45, 2, 22, -17, 0, -30, 25, 55};

int main()
{

sort(arr, arr+8); // sort the numbers

for(int j=0; j<8; j++) // display sorted array


cout << arr[j] << ' ';

cout << endl;

return 0;
}
Searching for a pattern
// searches one container for a sequence in another container

#include <iostream>
#include <algorithm>

using namespace std;

int source[] = { 11, 44, 33, 11, 22, 33, 11, 22, 44 };

int pattern[] = { 11, 22, 33 };

int main()
{

int* ptr;

ptr = search(source, source+9, pattern, pattern+3);

if(ptr == source+9) // if past-the-end


cout << “Better luck next time\n";

else
cout << "Match at " << (ptr - source) << endl;

return 0;
}
Merging
// merges two containers into a third

#include <iostream>

#include <algorithm> //for merge()

using namespace std;

int src1[] = { 2, 3, 4, 6, 8 };

int src2[] = { 1, 3, 5 };

int dest[8];

int main()
{ //merge src1 and src2 into dest

merge(src1, src1+5, src2, src2+3, dest);

for(int j=0; j<8; j++) // display dest


cout << dest[j] << ' ';

cout << endl;

return 0;
}
STL: Sequence Containers
Vectors
Example #1
// demonstrates push_back(), operator[], size()
#include <iostream>
#include <vector>
using namespace std;

int main()
{

vector<int> v; // create a vector of ints

v.push_back(10); // put values at end of array


v.push_back(11);
v.push_back(12);
v.push_back(13);

v[0] = 20; // replace with new values


v[3] = 23;

for(int j=0; j<[Link](); j++) // display vector contents


cout << v[j] << ' '; // 20 11 12 23

cout << endl;

return 0;
}
Example #2
// demonstrates constructors, swap(), empty(), back(), pop_back()
#include <iostream>
#include <vector>
using namespace std;

int main()
{ // an array of doubles

double arr[] = { 1.1, 2.2, 3.3, 4.4 };

vector<double> v1(arr, arr+4); // initialize vector to array

vector<double> v2(4); // empty vector of size 4

[Link](v2); // swap contents of v1 and v2

while( ![Link]() ) // until vector is empty,


{
cout << [Link]() << ' '; // display the last element
v2.pop_back(); // remove the last element
} // output: 4.4 3.3 2.2 1.1
cout << endl;

return 0;
}
Example #3
// demonstrates insert(), erase()

#include <iostream> cout << "\nAfter insertion: ";


#include <vector>
for(j=0; j<[Link](); j++) // display all elements
using namespace std;
cout << v[j] << ' ';
int main()
{ [Link]( [Link]()+2 ); // erase element 2

int arr[] = { 100, 110, 120, 130 }; //an array of ints cout << "\nAfter erasure: ";

vector<int> v(arr, arr+4); // initialize vector to array for(j=0; j<[Link](); j++) // display all elements
cout << v[j] << ' ';
cout << "\nBefore insertion: ";

for(int j=0; j<[Link](); j++) // display all elements cout << endl;
cout << v[j] << ' ';
return 0;
[Link]( [Link]()+2, 115); // insert 115 at element 2 }
Why vectors?
• Arrays: Fixed size, Vectors: expandable
• Why not manage a `expandable’ array on your own (e.g., char *)?
• If you allocate memory, then you need to ensure delete happens
• Use the right form for new/delete
• Delete only once
• Easier to let C++ STL handle the memory to prevent “leaks” and also do “less work”

Getting a pointer from a vector:

void doSomething(const int* pInts, int numlnts);

vector<int> v;

if (![Link]())
{
doSomething(&v[0], [Link]());
}
Lists
Example #1
// demonstrates push_front(), front(), pop_front()

#include <iostream>
#include <list>

using namespace std;

int main()
{

list<int> ilist;

ilist.push_back(30); // push items on back


ilist.push_back(40);
ilist.push_front(20); // push items on front
ilist.push_front(10);

int size = [Link](); // number of items

for(int j=0; j<size; j++)


{
cout << [Link]() << ' '; // read item from front
ilist.pop_front(); // pop item off front
}
cout << endl;

return 0;
}
Example #2
// demonstrates reverse(), merge(), and unique()

#include <iostream> [Link](); // reverse list1: 10 20 30 40


#include <list>
using namespace std; [Link](list2); // merge list2 into list1

int main() [Link](); // remove duplicate 20 and 30


{
int j; int size = [Link]();

list<int> list1, list2; while( ![Link]() )


{
int arr1[] = { 40, 30, 20, 10 }; cout << [Link]() << ' '; // read item from front

int arr2[] = { 15, 20, 25, 30, 35 }; list1.pop_front(); // pop item off front
}
for(j=0; j<4; j++) cout << endl;
list1.push_back( arr1[j] ); // list1: 40, 30, 20, 10
return 0;
for(j=0; j<5; j++) }
list2.push_back( arr2[j] ); // list2: 15, 20, 25, 30, 35
Deques
The one and only example
// demonstrates push_back(), push_front(), front()

#include <iostream>
#include <deque>
using namespace std;

int main()
{

deque<int> deq;

deq.push_back(30); // push items on back


deq.push_back(40);
deq.push_back(50);
deq.push_front(20); // push items on front
deq.push_front(10);

deq[2] = 33; // change middle item

for(int j=0; j<[Link](); j++)


cout << deq[j] << ' '; // display items

cout << endl;

return 0;
}
A mini-quiz
vector<int> v;

if( [Link]() == 0) (OR) if( [Link]())

/////////////////////////////////////////////////////////////////////////////

vector<int> v1;
vector<int> v2 = { 7, 5, 16, 8 };

[Link]([Link]() + [Link]() /2, [Link]());

(OR)

[Link]();
copy([Link]() + [Link]() / 2, [Link](), back_inserter(v1 ));

/////////////////////////////////////////////////////////////////////////////

vector<bool> v;

bool *pb = &v[0];


Solutions
1. Checking for Empty Containers
The Choice: if ([Link]()) vs. if ([Link]() == 0)
• Winner: [Link]()
• Why: It clearly expresses "is this empty?" rather than performing a math comparison.
◦Ef ciency: On some containers (like std::list), empty() is always O(1), while size() might have to count every element
(O(n)).
2. Copying a Range of Data
The Choice: [Link](range) vs. [Link]() + std::copy()
• Winner: [Link]()
• Why:
◦ Optimization: assign() is a member function that can reallocate memory once for the entire range.
◦ Safety: std::copy with back_inserter calls push_back repeatedly, which may cause multiple expensive memory
reallocations as the vector grows.
3. The vector<bool> Pointer Trap
The Code: vector<bool> v; bool *pb = &v[0];
• Result: Compile-Time Error
• The Reason: * vector<bool> is a "specialized" container that packs bits to save space (1 bit per bool).
◦ Since CPU memory addresses can only point to bytes, not individual bits, you cannot take the address of a packed boolean.
• The Fix: Use vector<char> if you need a collection of addressable booleans.
fi
23

Accessing sequence containers


pop_front() pop_back()

The Standard Template Library insert()


751

VECTOR DEQUE
push_back() push_front() push_back()

6 0 1 2 3 4 5 6
0 1 2 3 4 5 6 46 46

10 15 20 25 30 35 40 10 15 20 25 30 35 40

45
45 5
intVect [3] = = 25 intDeque [3] = = 25
pop_back pop_back()
pop_back()

FIGURE 15.2
LIST Sequence containers.
push_back()
push_front()

6 16 Iterators
10 15 20 25 30 35 40
Iterators may seem a bit mysterious, yet they are central to the operation of the STL. In this
45 section we’ll first discuss the twin roles played by iterators: as smart pointers and as a connec-
5
23 tion between algorithms and containers. Then we’ll show some examples of their use.
pop_front() pop_back()

insert()

DEQUE
push_front() push_back()
Iterators
Why iterators?
• The Bridge (Decoupling): Connects any algorithm to any container. One std::find
works on a vector, list, or deque without changing a line of code.

• Abstracted Logic: Standardizes movement. Whether jumping memory addresses or


following pointer chains, the command is always it++.

• Safety & Boundaries: Uses the begin() and end() pattern to de ne clear ranges,
preventing common "off-by-one" errors.

• Modern Ef ciency: Powers range-based for loops and high-performance STL algorithms
through a consistent, optimized interface.
fi
fi
er 15
Table 15.7 shows which operations each iterator supports.

TABLE 15.7 Capabilities of Different Iterator Categories

Random Access Step Step Random


Forward Read Write Back Access
Iterator Type ++ value=*i *i=value -- [n]
Random access iterator x x x x x
Bidirectional iterator x x x x
Bidirectional
Forward iterator x x x
Output iterator x x
Input iterator x x

Forward As you can see, all the iterators support the ++ operator for stepping forward through the con-
tainer. The input iterator can use the * operator on the right side of the equal sign (but not on
the left):
value = *iter;

Input Output The output iterator can use the * operator only on the right:
*iter = value;

E 15.3 The forward iterator handles both reading and writing, and the bidirectional iterator can be
categories.
decremented as well as incremented. The random access iterator can use the [] operator (as
algorithm needs only to step forward through a container, reading (butwell as simple
not writing arithmetic operators such as + and -) to access any element quickly.
to) one
fter another, it can use an input iterator to connect itself to the container.
An Actually,
algorithminput
can always use an iterator with more capability than it needs. If it needs a for-
ors are typically used, not with containers, but when reading from files or cin.
ward iterator, for example, it’s all right to plug it into a bidirectional iterator or a random
algorithm steps through the container in a forward direction but writesaccess
to the container
iterator.
Example #1
// iterator and for loop for output
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;

int main()
{
int arr[] = { 2, 4, 6, 8 };

list<int> theList;

for(int k=0; k<4; k++) // ll list with array elements


theList.push_back( arr[k] );

list<int>::iterator iter; //iterator to list-of-ints

for(iter = [Link](); iter != [Link](); iter++)


cout << *iter << ' '; //display the list

cout << endl;

return 0;
}
fi
Example #2
// demonstrates reverse iterator
#include <iostream>
#include <list>
using namespace std;

int main()
{

int arr[] = { 2, 4, 6, 8, 10 }; // array of ints

list<int> theList;

for(int j=0; j<5; j++) // transfer array


theList.push_back( arr[j] ); // to list

list<int>::reverse_iterator revit; // reverse iterator

revit = [Link](); // iterate backwards

while( revit != [Link]() ) // through list,


cout << *revit++ << ' '; // displaying output

cout << endl;

return 0;
}

You might also like