Standard Template Library - dupa cum ii spune si numele, STL este o biblioteca standard, generica pentru iteratori, containere, algoritmi, obiecte de tip functie, alocare de memorie, etc.
Un interator este folosit pentru a parcurge, a itera o lista de obiecte. Interatorul este conceput a fi ca functionalitate in C++ asemanator cu un pointer, in consecinta, pentru interatori avem urmatorii operatori:
it++
it--
*it //returneaza o referinta catre obiectul curent
Tipuri de iteratori:
- Input_Iterator
- Output_Iterator
- ForwardIterator (merge doar catre dreapta)
- BidirectionalIterator
- RandomAccessIterator
In aceasta categorie includem structuri de date standard, cum ar fi:
vector
list
set
(multime)map
hash
stack
queue
priority_queue
#include "vector"
Metodele clasei vector
din STL:
begin
: returneaza un iterator catre pointeaza catre prima componenta a vectoruluiend
: returneaza interator catre componenta ce ar trebui sa fie dupa ultimaempty
: verifica daca este gol (nu are componente)erase
: primeste un parametru de tip iterator catre o componenta pe care o sterge (o elimina din vector); exista sierase
cu doi parametri care sterge elementele de la start pana la finalclear
: curata vectorul (elimina toate componentele)resize
: redimensioneaza vectorul la lungimea primita ca parametruinsert
: primeste doi parametri: un interator si o o valoare pe care o insereaza pe pozitia indicata de operatorpush_back
: adauga la sfarsit valoarea primita ca parametrupop_back
: scoate ultima componenta din vector si scade dimensiuneasize
size
: returneaza numarul de componente al vectoruluicapacity
: returneaza numarul de casute de memorie alocate pentru vector
Operatori:
=
[]
==
In STL avem implementati algoritmii standard pe care ii putem imparti in mai multe categorii:
- non-mutated: fara mutare:
find
,count
,search
,equal
- mutated:
replace
,copy
,swap
,generate
,fill
,reverse
,rotate
,particion
- sorting:
sort
,binary_search
,merge
,set
- operatii cu heapuri:
min
,max
,permutation
,compare
Pentru a folosi algoritmii din STL trebuie sa includem fisierul antet:
#include "algorithm"
int a[100];
vector<int> v;
...
sort(a, a + n);
sort(a + k, a + h); //sortez de la pozitia lui k pana
//inainte de pozitia lui h
binary_search(first, last, v);
// se cauta v intre first si pana
// inainte de last si returneaza
// un bool
lower_bound(first, last, v);
upper_bound(first, last, v);
// returneaza iterator catre
// pozitia gasita
// in cazul in care lower_bound sau upper_bound
// nu gaseste valoarea v, se returneaza iterator
// catre componenta care s-ar afla inaite/dupa v,
// daca v s-ar insera
for(it:container)
for(&it:cont)
vector<int> v;
for(int i = 0; i < size; i++)
cout << v[i] << endl;
for(int c:v)
cout << c << endl;
// c se initializeaza succesiv cu valorile componentelor
// vectorului v
// pentru modificare:
for(int &c:v)
c++;
// incrementam fiecare componenta a vectorului v
// c = referinta succesiva pentru elemente
Putem declara variabile ca fiind auto
. In aceasta situatie, compilatorul identifica tipul variabilei respective din contextul programului.
int x = 1;
auto y = x + 1.1;
// la compilare, se va identifica tipul lui y ca fiind
// double , deoarece 1.1 este de tip double
for(auto &c:v)
c++;
Este contraindicat a se exagerat cu folosirea tipului auto
.
O lambda exresie se defineste sub forma:
[...](...) -> tip_returnat {implemetare} (...)
1 2 3 4 5
Prima sectiune poarta denumirea de zona de conditii de captare a variabilelor.
A doua sectiune reprezinta parametri expresiei.
A cincea sectiune: se pot da optional valori pentru parametri (initializeaza parametri din sectiunea 2).
Desi se implementeaza diferit fata de o functie, din cauza structurii, o lambda expresie se evalueaza absolut asemanator cu un apel de functie.
In sectiunea 1 pot fi enumerate variabilele ce sunt vizibile in corpul expresiei (sectiunea 4). Orice variabila enumerata este accesibila in sectiunea 4 prin valoare sau prin referinta. Daca in prima sectiune in enumerare apare =
, atunci, toate variabilele ce nu sunt enumerate in aceasta sectiune sunt vizibile in expresie prin valoare. Daca in enumerare apare &
in enumerare, toate variabilele ce nu se enumera in prima sectiune sunt vizibile in expresie prin referinta.
Daca o functie in C/C++ nu poate fi implementata in interiorul altei functii, o lambda expresie poate aparea in corpul unei functii.
Tipul returnat nu este obligatoriu a fi specificat, mai ales daca lambda expresia nu returneaza nicio valoare. Mai mult, putem omite tipul returnat, lambda expresia returneaza o valoare, a carui tip, daca nu este specificat explicit, se deduce din context.
void main()
{
int x, y;
cin >> x >> y;
auto cmmdc = [](int a, int b)
{
int r;
for(;b;r = a % b, a = b, b = r)
return a;
};
cout << cmmdc(x, y) << endl;
// 5
// dupa denumirea lambda expresiei, intre paranteze
// se dau valorile pentru parametri, care devin
// practic sectiunea 5, care nu a fost data pentru
// cmmdc
cout << cmmdc(x + 1, y - 1) << endl;
}
int a = 1, b = 2, c = 3, d = 4;
auto e1 = [a,b](int x) {return a * x + b;};
// a si b nu pot fi modifica
// a++ <- incorect
auto e2 = [&,b](int x) {return ;};
// toate variabilele sunt cunoscute in lambda
// expresie si pot fi modificate, cu exceptia lui b
auto e3 = [=,&a](int x) {a++; return a * x + b - c + d;};
// corect
// a, b, c, d sunt cunoscute in expresie
// doar a poate fi modificata
auto e4 = [=]...
// toata variabilele sunt cunoscute,
// dar nu pot fi modificate
auto e5 = [&]...
// toata variabilele sunt cunoscute
// si pot fi modificate
vector<int> v;
...
int* p = &v[0];