STL !!!generic programming!!! Anar Manafov ([email protected]) STL (Standard Template Library) or STL stands for Stepanov and Lee The Evolution STL is not a new library.

Download Report

Transcript STL !!!generic programming!!! Anar Manafov ([email protected]) STL (Standard Template Library) or STL stands for Stepanov and Lee The Evolution STL is not a new library.

STL
!!!generic programming!!!
Anar Manafov ([email protected])
STL (Standard Template Library)
or STL stands for Stepanov and Lee
The Evolution
STL is not a new library as compared to other
libraries.
Originally, the development of the STL was started by
Alexander Stepanov at HP in 1979. Later, he was
joined by David Musser and Meng Lee.
In 1994, STL was included into ANSI and ISO C++.
http://www.stepanovpapers.com/
recommended link (Al Stevens Interviews Alex Stepanov, March 1995 issue of Dr. Dobb's Journal, ):
http://www.sgi.com/tech/stl/drdobbs-interview.html
STL Components
Here is a list of elements of the STL. The first three of them are fundamental items.
- Container
(An object that holds other objects)
- Algorithm (A function that acts on containers)
- Iterator (A pointer-like object)
- Allocator (This item manages memory allocation in a container)
- Adaptor (Transforms one object into another)
- Predicate (A function that returns a boolean value, true or false.)
- Function Object (A class that defines operator().)
Recommended link: http://www.sgi.com/tech/stl/ and http://www.sgi.com/tech/stl/stl_index.html
STL Components
containers, iterators, algorithms
vector
<T>
sort
list
<T>
find
containers, iterators, algorithms
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
int ia[10]={33,17,11,88,43,99,6,9,12,7};
int main(){
vector<int> x(ia,ia+10);
33 17 11 88 43 99 6 9 12 7
sort(x.begin(), x.end());
end()
begin()
6 7 9 11 12 17 33 43 88 99
// grab value to search for
int s_value;
cin >> s_value;
// search for an element
vector<int>::iterator found;
found=find(x.begin(),x.end(),s_value);
if(found != x.end()) {
cout << "search value found!\n";
}
else {
cout << "search value not found!\n";
}
}
list instead of vector
#include <list>
#include <algorithm>
#include <iostream>
using namespace std;
int ia[10]={33,17,11,88,43,99,6,9,12,7};
int main(){
list<int> x(ia,ia+10);
sort(x.begin(), x.end());
// grab value to search for
int s_value;
cin >> s_value;
// search for an element
list<int>::iterator found;
found=find(x.begin(),x.end(),s_value);
if(found != x.end()) {
cout << "search value found!\n";
}
else {
cout << "search value not found!\n";
}
}
Algorithms with built-in arrays
#include <algorithm>
#include <iostream>
using namespace std;
int ia[10]={33,17,11,88,43,99,6,9,12,7};
int main(){
int s_value;
cout << "enter search value: ";
cin >> s_value;
int *found;
found=find(&ia[0],&ia[10],s_value);
if(found != ia+10) ...
Containers
Sequence Containers
Vector
List
Deque
Stack
Queue
Adaptor
Priority_queue
Associative Containers
Map
Multimap
Set
Multiset
Almost Containers
Built-in arrays, strings, valarrays, bitsets
Containers
Container
Vector:
Deque:
List:
Set/Multiset:
Map/Multimap:
string Type
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
string s1("Hello");
string s2("World");
cout << s1 + " " + s2 + '\n';
string s3(s1 + " " + s2);
cout << '\"'<< s3 << "\" has " << s3.length()
<< " characters" << endl;
replace(s3.begin(), s3.end(), 'W', 'w');
cout << s3 << endl;
Constructors
container()
container(n)
(not for ass. cont.)
container(n,x) (not for ass. cont.)
container(first,last)
container(c)
~container()
Stack, Queue, List Operations
push_back()
pop_back()
push_front()
pop_front()
insert(p,x)
insert(p,n,x)
insert(p,first,last)
erase(p)
erase(first,last)
clear()
Algorithms
•
•
•
•
•
•
•
•
•
copy
sort
find
fill
partition
insert, delete
union, intersection
accumulate
...
Iterators
• The glue that makes it possible to use generic
algorithms and orthogonalize those
algorithms from the data structures
• An iterator i is a generalized means of
traversing a data structure:
– for an array, an array index or a pointer
• Dereferencing an iterator, *i, is guaranteed to
give the item, but an iterator does not obey all
pointer operations
Iterators, Element Access
begin()
end()
rbegin()
rend()
front()
back()
[]
at()
Points to first element
Points to one-past-last element
Points to first element of reverse seq.
Points to one-past-last element of rev. seq.
First element
Last element
Subscripting, unchecked access
Subscripting, checked access
Iterator Operations
output
Read
Access
Write
Iteration
Comparison
input
bidirectional
random-access
=*p
=*p
=*p
=*p
->
->
->
-> []
*p=
*p=
*p=
++
++
++ --
++ -- + -
== !=
== !=
== !=
== != < >
*p=
++
forward
Iterators (continued)
container<T>::iterator first=c.begin();
container<T>::iterator last=c.end();
[first,last)
++i;
first == last;
i != last;
i + n;
(long jump)
*i = x;
x = *i;
Nonmodifying Sequence Operations
for_each()
find()
find_if()
find_first_of()
adjacent_find()
count()
count_if()
mismatch()
equal()
search()
find_end()
search_n()
list<Person*> all;
...
for_each(all.begin(),all.end(),Print(cout));
Function objects
class bThan{
public:
bThan(int x): testVal(x) {}
const int testVal;
bool operator()(int val){return val>testVal;}
};
list<int>::iterator firstBig =
find_if(aList.begin(),aList.end(),bThan(12));
OO ?
• STL is not OO, is OOP dead?
• Not all problems are best solved in OOP
fashion!
• Many problems are best solved in an OOP
manner.
• Know as much as you can about as many
styles of programming as you can, an use the
style most appropriate to the problem.
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
map<string, long, less<string> > directory;
directory["Anar"] = 2128;
directory["Victor"] = 1395;
directory["Demo"] = 12344;
string name;
while (cin >> name)
{
if ( directory.find(name) != directory.end() )
cout << "The phone number for " << name << " is " << directory[name] << endl;
else
cout << "Sorry, no listing for " << name << endl;
}
}
#include <iostream>
#include <map>
#include <string>
using namespace std;
typedef map<string, long, less<string> > Directory_t;
typedef Directory_t::value_type Entry;
int main()
{
Directory_t directory;
// Will change the value of the key or insert if the key is exist already
directory["Anar"] = 2128;
// will insert or fail if the key is exist already
directory.insert ( make_pair<string, long>("Victor", 1395) );
directory.insert( Entry("Demo", 12344) );
string name;
while (cin >> name)
{
Directory_t::iterator iter = directory.find(name);
if ( iter != directory.end() )
cout << "The phone number for " << iter->first << " is " << (*iter).second << endl;
else
cout << "Sorry, no listing for " << name << endl;
}
}
Some real life examples
small, but very handy!
/*! \fn void TrimRight(std::basic_string<_T> &_str, const std::basic_string<_T> &_Val)
\brief Trims trailing characters from the string.
\param _Val - [in] The target characters to be trimmed.
*/
template<typename _T>
void TrimRight(std::basic_string<_T> &_str, const std::basic_string<_T> &_Val)
{
_str.resize( _str.find_last_not_of( _Val ) + 1 );
}
/*! \fn void TrimLeft(std::basic_string<_T> &_str, const std::basic_string<_T> &_Val)
\brief Trims leading characters from the string.
\param _Val - [in] The target characters to be trimmed.
*/
template<typename _T>
void TrimLeft(std::basic_string<_T> &_str, const std::basic_string<_T> &_Val)
{
_str.erase( 0, _str.find_first_not_of( _Val ) );
}