0% found this document useful (0 votes)
163 views

C++ STL

The document discusses the C++ Standard Template Library (STL). It provides definitions and examples of the major STL components - containers, algorithms, iterators and functors. Containers store and organize data, algorithms perform operations on container elements, iterators access container elements, and functors are function objects. The document also discusses how templates enable generic programming with containers, algorithms and classes in C++. Examples show how to use vectors, algorithms like sort, and iterators to iterate over container elements.
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
163 views

C++ STL

The document discusses the C++ Standard Template Library (STL). It provides definitions and examples of the major STL components - containers, algorithms, iterators and functors. Containers store and organize data, algorithms perform operations on container elements, iterators access container elements, and functors are function objects. The document also discusses how templates enable generic programming with containers, algorithms and classes in C++. Examples show how to use vectors, algorithms like sort, and iterators to iterate over container elements.
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 11

----------------------------------------------------

// C++ STL - Standard Library


----------------------------------------------------
// What is STL ?
* A library of powerful,reusable,adaptable,generic classes and functions
* Implememted using C++ templates
* implements common data structures and algorithms
* Huge class Library

// Why to use STL?


* Assortment of commonly used containers
* Known time and size complexity
* Tried and Tested - reusability !!!
* Consistent,fast and type-safe
* Extensible

//major components
1.Containers
2.Algorithms
3.Iterators
4.Functors

---------------------------------------------------------
//containers -- collection of objects or primitive types
---------------------------------------------------------
* A container is a way that stored data is organized in memory

* The STL containers are implemented by template classes,


so they can be easily customized to hold different kinds of data.

* Containers also include member functions for more specific tasks.

Examples
1.vector
2.List
3.deque
4.set
5.multiset
6.map
7.multimap
*offer more functonaities than arrays
*use algorithms to work with data in containers

------------------------------------------------------------------------------
//Algorithms -- functions for processing sequence of elements from containers
------------------------------------------------------------------------------
* Algorithms in the STL are procedures that are applied to containers to process
their data in various ways.

* Algorithms are represented by template functions. Rather, they are standalone


functions.

* These functions are not member functions of the container classes.

*Includes 1.modifying 2.non Modifying and 3.sorting algorithms


*perform variety of powerful operations
*Examples
// find find_if search search_n count mismatch
copy replace
*Do not need to write your own methods to perform common operations

-------------------------------------------------------------
// Iterators -- Generate sequence of element from containers
-------------------------------------------------------------

* Iterators are a generalization of the concept of pointers:

* they point to elements in a container. You can increment an iterator, as you can
a pointer, so it points in turn to each element in a
container.

* Iterators are a key part of the STL because they connect algorithms with
containers.

*cycles through a range of values such as container elements


*Examples
advance distance begin end reverse_iterator
move_iterator
Five different types
1.input - used to read values
2.output- used to write values
3.Forward - read,write and move forward
4.Bidirectional - read, write, move forward and backward
5.Random access - move freely

--------------------------------------------------------
// Functors
* Function objects
* Overload the operator function call - operator()
* create objects that look like function

-------------------------------------------------------------------

// A simple example

#include <vector>
#include <algorithm>

std::vector<int> v {1,5,3};

// sort a vector
std::sort(v.begin(), v.end());

for (auto elem: v)


cout << elem << endl;
/* 1
3
5 */

// reverse a vector
std::reverse(v.begin(),v.end());

for (auto elem: v)


cout << elem << endl;
/* 5
3
1 */
// Accumulate

int sum {};

sum = std::accumulate(v.begin(),v.end(),0); // 0 - for int , 0.0 - for double

cout << sum << endl;


// 9 // 1+3+5

---------------------------------------
// Types of Containers
--------------------------------------
1. Sequence containers (// maintain the order of stored elements)
. array , vector , list , forward_list , deque
2. Associative containers (// predefined order or no order)
. set , multi set , map , multi map
3. container adapters (// not support iterators)
. stack , queue , priority queue

---------------------------------------
// Types of Iterators
--------------------------------------
1. input iterators - from the container to the program
2. output iterators - from the program to the container
3. forward interators - navigate one item at a time in one direction
4. Bi-directional iterators - navigate one item at a time both directions
5. random access iterators - directly access a container item

---------------------------------------
// Types of Algorithms
--------------------------------------
. About 60 algorithms in the STL
1. non-modifying
2. modifying

-------------------------------------------------------------
//Generic Programming with macros
-------------------------------------------------------------
. Generic programming
writing code that works with a variety of types as arguments ,
as long as those argument types meet specific syntactic and
semantic requirements
1. Macros
2. Function templates
3. class templates

// macros #define
. c++ preprocessor directive
. no type information
. simple substitution

#define MAX_SIZE 100 // removed


#define PI 3.1419 // removed

if (num > MAX_SIZE) // replace MAX_SIZE with 100


cout << "too big ";
double area = PI * r * r; // replace PI with 3.1419
// Macros with arguments
#define MAX(a,b) ((a>b) ? a : b )

cout << MAX(20,30); // 30


cout << MAX(2.4,4.5); // 4.5
cout << MAX('A','C'); // C

#define SQUARE(a) a*a

result = square(5);
result = 5*5;

result = 100 / SQUARE(5); // expect 4


result = 100 / 5 * 5 ; // get 100!

// all the arguments of macros must wrap up inside parenthesis

#define SQUARE(a) ((a)*(a))


result = 100 / SQUARE(5);
result = 100 / ((5)*(5)); // 4

-------------------------------------------------------------
//Generic Programming with function templates
-------------------------------------------------------------
// What is a C++ Template ?
. Blueprint
. function and class templetes
. Allow plugging-in any data type
. compiler generates the appropriate function/class from the blueprint
. Generic programming/meta-programming

// max function as a template function


. we need to tell the compiler this is a template function
. We also need to tell it that T is the template parameter
* we may also use class instead of typename

template <typename T> // template <class T>


T max(T a , T b)
{
return (a > b) ? a : b ;
}
. now the compiler can generate the appropriate function from the template
. note , this happens at compile time
int a {10};
int b {20};

cout << max<int>(a,b);

. many times the compiler can deduce the type and the template parameter is not
needed
. Depending on the type of a and b , the compiler will figure it out
cout << max<double>(c,d);
cout << max(c,d);
.We can use almost any type we need
char a {'A'};
char b {'Z'};

cout << max(a,b) << endl;


. Notice the type MUST support the > operator either natively or as an overloaded
operator (operator >)

// the following wont compile unless player overloads operator >


player p1{"hero", 10 ,20};
player p2{"villain",30,40};

cout<<max<player>(p1,p2);

// multiple types as template parameters


. we can have multiple template parameters
. and their types can be different

template <typename T1, typename T2>


void func(T1 a , T2 b){
cout << a << " " << b;
}

func<int,double>(10,20.6);
func('A',12.4);

-------------------------------------------------------------
//Generic Programming with class templates
-------------------------------------------------------------
// what is class templete?

. similar to function template , but at the class level


. Allows plugging-in any data type
. compiler generates appropriate class from blue print

template <typename T>


class item {
private:
string name;
T value;

public :
item(string name , T value)
:name{name},value{value}
{}
string get_name() const {
return name;

T get_value () const {return value;}


};

item<int> item1 {"larry",1};


item<double> item2 {"house", 2};
item<string> item3 {"ranjith","kumar"};
vector <item<int>> vec;

// multiple types as template parameters


. we can have multiple template parameters
. and their types can be different

template <typename T1, typename T2>


struct my_pair{
T1 fistr;
T2 second;
};

my_pair<string,int> p1{"frank" , 10};


my_pair<int,double> p1{6, 10.4};
vector <my_pair<int , double>> vec;

-------------------------------------------------------------
//Introduction to STL containers
-------------------------------------------------------------
. data structures can store object of almost any type
. template based classes
. Each container has member functions
. some are specific to container
. others are available to all containers
. Each container has an associated header file
#include <container_type>

// containers - common
function Description
1. defaut constructors initaializes an empty container
2. overaloaded constructors initializes containers with many options
3. copy constructor initializes container as a copy of another container
4. move constructor Move existing container to new container
5. Destructor Destroys a container
6. copy assignment(operator =) copy one container to another
7. move assignment(operator =) move one containetr to another
8. size returns the number of elements in the container

9. empty returns boolean - is the container empty ?


10. insert insert an element into an container
11. operator< and operator<= returns boolean - compares contents of 2 containers
12. operator> and operator>= returns boolean - compares contents of 2 containers
13. operator== and operator!= returns boolean - are the contents of 2
containers equal or not
14. swap swap the elements of 2 containers
15. erase remove the element(s) from the container
16. clear remove all the elements from the container
17. begin and end return iterators to first element or end
18. rbegin and rend return reverse iterators to first element or end
19. cbegin and cend return const iterators to first element or end
20. crbegin and crend return const reverse iterators to first element or
end

// what types of elements can we store in containers ?


. A copy of the elements will be stored in the container
. All primitives OK
. Element should be
. copyable and assignable (copy constructor / copy assignment)
. Movable for efficiency (move constructor / move assignement)
. ordered associative containers must be able to compare elements
. ordered<, operator==

-------------------------------------------------------------
//Introduction to STL Iterators
-------------------------------------------------------------
. Allows abstracting an arbitrary container as a sequence of elements
. They are objects that work like pointers by design
. Most comntainer classes can be traversed with iterators
// declaring iterators
. iterators must be declared based on container type they will iterate over
container_type::iterator_type iterator_name;

std::vector<int>::iterator it1;
std::list<string>::iteraor it2;
std::map<string , string>::iterator it3;
std::set<char>::iterator it4;

// iterator begin and end methods


std::vector<int> vec {1,2,3};
vec.begin(); // --> first element
vec.end(); // --> location after last element

// initializing iterators
std::vector<int> vec {1,2,3};
std::vector<int>::iterator it = vec.begin();
// or
auto it = vec.begin();

// operations with iterators(it)


operation description Type of operator
++it pre-increment All
it++ post-increment All
it = it1 Assignemnt All
*it Dereference input and output
it-> Arrow operator input and output
it == it1 comparision for equality input
it != it1 comparision for inequality input
--it pre-decrement Bi-directional
it-- post-decrement Bi-directional
it+i , it+=i increment and decrement Random access
it-i , it-=i
it<it1 , it<=it1 comparision Random access
it>it1 , it>=it1
// using iteratos - std::vector
std::vector<int> vec {1,2,3};
std::vector<int>::iterator it = vec.begin;

while (it != vec.end()) {


std::cout << *it << " ";
++it;
}
// 1 2 3

for (auto it = vec.begin(); it != vec.end(); it++){


std::cout << *it << " ";
}
// 1 2 3

// using iterators - std::set


std::set<char> suits {'C' , 'H' , 'S' , 'D'};

auto it = suits.begin();

while (it != suits.end()){


cout << *it << " " << endl;
++it;
}
// C H S D
// Reverse iterators
. works in rverse
. Last element is the first and first is the last
. ++moves backward , -- moves forward

std::vector<int> vec {1,2,3};


srd::vector<int>::reverse_iterator it = vec.begin();

while (it != vec.end() ) {


cout << *it << " ";
++it;
}
// 3 2 1

// other iterators
. begin() and end() -- iterator
. cbegin() and cend() -- const_iterator
. rbegin() and rend() -- reverse_iterator
. crbegin() and crend() -- const_reverse_iterator

-------------------------------------------------------------
//Introduction to STL Algorithms
-------------------------------------------------------------
. STL algorithms work on sequences of container elements
provided to them by an iterator
. STL has many common an duseful algorithms
. Many algorithms require extra information inorder to do their work
. functors (function objects )
. function pointers
. Lambda expressions (C++11)

// Algorithms and iterators


. #include <algorithms>
. Different containers support different types of iterators
. determines the types of algorithms supported
. All STL algorithms except iterators as arguments
. determines the sequence obtained from the container

// Iterator invalidation
. iterators point to container elements
. its possible iterators become invalid during processing
. suppose we are iterating over a vector of 10 elements
. And we clear() the vector while iterating ? what happend ?
. undefined behavior - our iterators are pointing to invalid locations
-----------------------------------------------------
// example algorithm - 1.find with primitive types
. The find algorithm tries to locate the first occurance of an element
in a container
. Lots of variations
. Returns an iterator pointing to the located element or end()

std::vector<int> vec {1,2,3};


auto loc = std::find(vec.begin() , vec.end() , 3);

if (loc != vec.end()) // found it


cout << *loc << endl; // 3

// example algorithm - 2.find with user-defined types


. find needs to be able to compare object
. operator == is used and must be provided by your class

std::vector<player> team {/* assume initialized */};


player p {"hero" , 20 , 40};

auto loc = std::find(team.begin() , team.end() , p);

if (loc != vec.end()) // found it


cout << *loc << endl; // operator << called
--------------------------------------------------
// example algorithm - for_each
. for_each algorithm applies a function to each element in the iterator sequence
. function must be provided to the algorithm as
. functor (function object)
. function pointer
. Lambda expression (C++11)
. lets square each element

// for_each - 1. using a functor


struct Square_Functor {
void operator() (int x) { // overload () operator
std::cout << x * x << " ";
}
};

Square_Functor square ; // function object


std::vector<int> vec {1,2,3,4};

std::for_each(vec.begin(), vec.end(), square);


// 1 4 9 16

// for_each - 2. using a function pointer


void square(int x){
cout << x * x << endl;
}
std::vector<int> vec {1, 2, 3, 4};

std::for_each(vec.begin(), vec.end(), square);


// 1 4 9 16

// for_each - 3. using a lambda expression


std::vector<int> vec {1, 2, 3, 4};

std::for_each(vec.begin(), vec.end(),
[] (int x) { cout << x * x << endl;} ) //
lambda
// 1 4 9 6

-------------------------------------------------------------
// SEQUENCE CONTAINER - 1.ARRAY
-------------------------------------------------------------
std::array (C++11)
#include <array>
. fixed size - size must be known at compile time
. direct element access
. provides access to the underlying raw array
. use instead of raw arrays when possible
. All iterators available do not invalidate
std::array -- initialization and assignment

std::array<int , 5> arr1 {{1 , 2, 3, 4 ,5}}; // C++11 vs C++14

std::array<string , 3 >stooges {
string ("larry"},
"Moe",
string("curly"}
};

arr1 = {2,4,6,8,10};

// std::array -- common methods


std::array<int , 5> arr {1,2,3,4,5};
std::array<int , 5> arr1 {10,20,30,40,50};

cout << arr.size(); // 5 size


cout << arr.at(0); // 1 at(0)
cout << arr[1]; // 2 [1]

cout << arr.front(); // 1 front


cout << arr.back(); // 5 back

cout << arr.empty(); // 0 false empty


cout << arr.max_size(); // 5 max_size

cout << arr.fill(10); // fills all to 10


arr.swap(arr1); // swaps the 2 arrays
int *data = arr.data(); // get raw arry address

-------------------------------------------------------------
// SEQUENCE CONTAINER - 1.VECTOR
-------------------------------------------------------------
std::vector
#include <vector>
. Dynamic size
. handled automatically
. can expand and contract as needed
. elements are stored in contiguos memory as an array
. Direct element access (constant time )
. Rapid insertion and deletion at the back (constant time )
. insertion or removal of elements (linear time)
. All iterators available and may invalidate

std::vector
std::vector<int> vec {1,2,3};
front() - first element
back() - last element

vec.push_back(4); // add 4 at the back

// vector initialization and assignment


vector<int> vec {1,2,3,4,5};
vector<int> vec1 (10,100); // ten 100's

vector<string> stooges {
string ("larry"},
"Moe",
string ("curly"}
};

vec1 = {2,4,6,8,10};

vec.size(); // 5
vec.capacity(); // 5
vec.max_size; // a very large number
vec.at(0); // 1
vec[1]; // 2
vec.front(); // 1
vec.back(); // 5

person p1 {"larry" , 18};


vector<person> vec;

vector.push_back(p1); // add p1 to the back


vector.pop_back(); // remove p1 from the back

vec.push_back(person{"larry",18});
vec.emplace_back("larry",18}; // efficient - no moves no copies

vec1.empty(); // o false
vec1.swap(vec2); // swaps the 2 vectors
sort(vec1.begin(), vec1.end());

vector<int> vec1 {1,2,3,4,5};


vector<int> vec2{10,20,30,40,50};

auto it = std::find(vec1.begin(),vec1.end(),3); // 3rd position


vec1.insert(it,10); // 1,2,10,3,4,5

it = std::find(vec1.begin(), ve1.end(),4);
std::insert(it,vec2.begin(),vec2.eng());
// 1,2,10,3,10,20,30,40,50,4,5

// element access
at operator[] front back data

You might also like