03
Iun
2008

Intr-un articol anterior am vorbit despre clasa array din implementarea TR1 oferita de Microsft in VC++ 2008 Feature Pack. In acest articol voi aduce in discutie o alta clasa, tuple, si celelalte functii si clase din headerul cu acelasi nume.

Tipul tuple

Tuple este o secventa cu un numar fix de elemente, de tipuri diferite. Deosebirea fata de un array e ca in timp ce acest e o secventa omogena (toate elementele avand acelasi tip), tuple este o secventa eterogena (fiecare element putand avea un alt tip). Clasa tuple este una template, si se gaseste in fisierul <tuple> sub namespace-ul std::tr1. Desi teoretic numarul de elemente al unui tuple poate fi oricat (dar fix), in implementarea TR1 din VC++ 2008 Feature Pack, aceasta limita este de 15 elemente.

Premise

In exemplele din acest articol voi folosi un tuple cu trei elemente, un int, un double si un string. Pentru usurinta voi folosi aceasta definitie:

typedef std::tr1::tuple<int, double, std::string> tuple_ids;

De asemenea voi folosi functia de mai jos pentru afisarea unui tuple de tipul definit mai sus (voi reveni mai jos asupra detaliilor de acces la elementele unui tuple):

void print_tuple(const std::tr1::tuple<int, double, std::string>& t)
{
   std::cout << std::tr1::get<0>(t) << " "
             << std::tr1::get<1>(t) << " "
             << std::tr1::get<2>(t) << std::endl;
}

Creare tuple-uri

Cea mai simpla varianta de definire este cea folosind constructorul default:

tuple_ids t;
print_tuple(t);
0 0 

A doua optiune este folosirea constructorului cu parametrii:

tuple_ids t(1, 2.5, "trei");
print_tuple(t);

Rezultatul afisarii va fi:

1 2.5 trei

O a treia optiune pentru crearea unui tuple este folosirea functiei make_tuple din header-ul <tuple>.

tuple_ids t = std::tr1::make_tuple(10, 20.5, "treizeci");
print_tuple(t);
10 20.5 treizeci

Dimensiunea unui tuple

Pentru a obtine dimensiunea unui tuple (numarul de elemente) exista o clasa template numita tuple_size , care are un membru numit value care reprezinta dimensiunea unui tuple.

std::cout << "size: " << std::tr1::tuple_size<tuple_ids>::value << std::endl;
size: 3

Accesul la elemente

Pentru a accesa elementele se foloseste functia template get:

  • citire

    tuple_ids t(1, 2.5, "trei");
    std::cout << std::tr1::get<0>(t) << " "
              << std::tr1::get<1>(t) << " "
              << std::tr1::get<2>(t) << std::endl;
    

    afiseaza

    1 2.5 trei
    
  • sciere

    tuple_ids t;
    print_tuple(t);
    
    std::tr1::get<0>(t) = 10;
    std::tr1::get<1>(t) = 20.5;
    std::tr1::get<2>(t) = "treizeci";
    print_tuple(t);
    

    afiseaza

    0 0
    10 20.5 treizeci
    

Tipul elementelor

Exista o clasa numita tuple_element care impacheteaza tipul unui element al unui tuple. Aceasta clasa template are un typedef intern care este sinonim tipului unui element al unui tuple de un anumit index.

tuple_ids t(100, 200.5, "trei sute");

std::tr1::tuple_element<0, tuple_ids>::type val1 = std::tr1::get<0>(t);
std::tr1::tuple_element<1, tuple_ids>::type val2 = std::tr1::get<1>(t);
std::tr1::tuple_element<2, tuple_ids>::type val3 = std::tr1::get<2>(t);

std::cout << "val1 = " << val1 << std::endl;
std::cout << "val2 = " << val2 << std::endl;
std::cout << "val3 = " << val3 << std::endl;
100 200.5 trei sute

Operatori

Un prim operator important este cel de atribuire.

tuple_ids t1(1, 2.5, "trei");
print_tuple(t1);

tuple_ids t2;
t2 = t1;
print_tuple(t2);

tuple_ids t3(100, 200.5, "trei sute");
t1 = t3;
print_tuple(t1);
1 2.5 trei
1 2.5 trei
100 200.5 trei sute

Exista apoi operatorii == si !=, primul returnand true daca dimensiunea unui tuple e 0 sau daca fiecare element din primul tuple este egal cu fiecare element corespunzator din cel de-al doilea tuple, iar al doilea operator false daca N este 0 sau cel putin un element din primul tuple nu este egal cu elementul corespunzator din cel de-al doilea tuple. Nu pot fi comparate decat tuple-uri de acelasi fel.

tuple_ids t1(1, 2.0, "one");
tuple_ids t2(2, 2.0, "one");

std::cout << "t1 == t1: " << std::boolalpha << (t1 == t1) << std::endl;
std::cout << "t1 == t2: " << std::boolalpha << (t1 == t2) << std::endl;
t1 == t1: true
t1 == t2: false

Pe langa acestia mai exista si operatorii >, >=, < si <=. Toti acestia sunt definiti in termenii operatorului <. Acesta returneaza true cand N este mai mare ca 0 si cand primul element din primul tuple este mai mic decat elementul corespunzator din al doilea tuple.

tuple_ids t1(1, 2.0, "one");
tuple_ids t2(2, 2.0, "one");
tuple_ids t3(1, 3.0, "one");
tuple_ids t4(1, 2.0, "four");

std::cout << "t1 < t2: " << std::boolalpha << (t1 < t2) << std::endl;
std::cout << "t1 < t3: " << std::boolalpha << (t1 < t3) << std::endl;
std::cout << "t1 < t4: " << std::boolalpha << (t1 < t4) << std::endl;
t1 < t2: true
t1 < t3: true
t1 < t4: false

Legarea unor variabile la un tuple

Se poate crea un tuple din referinte la variabile folosind functia tie.

tuple_ids t(1, 2.5, "trei")

int v1 = 10;
double v2 = 20.5;
std::string v3 = "treizeci";
std::cout << "inainte de legare..." << std::endl;
std::cout << v1 << " " 
          << v2 << " "
          << v3 << std::endl;

std::tr1::tie(v1, v2, v3) = t;
std::cout << "dupa legare..." << std::endl;
std::cout << v1 << " " 
          << v2 << " "
          << v3 << std::endl;
inainte de legare...
10 20.5 treizeci
dupa legare...
1 2.5 trei

Swapping

Continutul a 2 tuple de acelasi fel poate fi inversat fie folosing metoda swap din clasa tuple, fie functia cu acelasi nume din header-ul <tuple>.

tuple_ids a(1, 2, "trei");
tuple_ids b(4, 5, "sase");

std::cout << "inainte de swapping" << std::endl;
print_tuple(a);
print_tuple(b);

std::cout << "dupa primul swapping" << std::endl;
a.swap(b);
print_tuple(a);
print_tuple(b);

std::cout << "dupa al doilea swapping" << std::endl;
std::tr1::swap(a, b);
print_tuple(a);
print_tuple(b);
inainte de swapping
1 2 trei
4 5 sase
dupa primul swapping
4 5 sase
1 2 trei
dupa al doilea swapping
1 2 trei
4 5 sase

Support debugger

Ca si in cazul clasei array si a celorlalte containere STL, debugger-ul arata continutul unui array intr-un mod usor de vizualizat, ceea ce este de mare ajutor pentru debugging.

Concluzii

Daca clasa array este utila pentru lucrul cu secvente cu dimensiune fixa, dar omogene, toate elementele avand acelasi tip, clasa tuple este utila pentru secventa cu dimensiune fixa dar eterogene, intrucat fiecare element poate fi de alt tip.

[phpBB Debug] PHP Warning: in file [ROOT]/phpbb/db/driver/mysqli.php on line 317: mysqli_free_result(): Couldn't fetch mysqli_result