This is an old revision of the document!
H Standard Template Libray (STL) είναι βιβλιοθήκη της C++ που αποτελεί αναπόσπαστο τμήμα της stardard βιβλιοθήκης της γλώσσας. Αποτελείται από κλάσεις για προσωρινή αποθήκευση πληροφορίας σε ένα πρόγραμμα που ονομάζονται containers, κλάσεις για διάτρεξη των containers (ονομάζονται iterators) και αλγορίθμους. Οι αλγόριθμοι είναι συναρτήσεις που κατά κανόνα λειτουργούν με την βοήθεια των iterators πάνω στους διαθέσιμους containers.
Βασικό χαρακτηριστικό της STL είναι ότι οι κλάσεις (containers και iterators) και οι συναρτήσεις των αλγορίθμων είναι γενικευμένες, ώστε να μπορούν να εφαρμοστούν με ασφάλεια σε οποιονδήποτε τύπο δεδομένων. Για να το επιτύχουν αυτό, χρησιμοποιούν templates.
Στο παρακάτω διάγραμμα περιέχονται το σύνολο των containers που παρέχει η βιβλιοθήκη STL.
Οι containers της STL διακρίνονται στις εξής κατηγορίες:
Κατά την ένθεση ενός στοιχείου σε ένα container, δημιουργείται πάντοτε ένα αντίγραφο του στοιχείου σε αυτόν. Για παράδειγμα, για την ένθεση στοιχείων της κλάσης Student μέσα σε ένα container list τα στοιχεία θα αντιγραφούν εντός του list στο τέλος της λίστας (οι μέθοδοι insert_back και emplace_back εισάγουν στο τέλος της λίστας) ως εξής:
#include <iostream> // std::cout #include <algorithm> // std::copy #include <list> // std::list #include <array> // std::array #include "Student.hpp" int main () { Student students[] = { Student("Peter_Pan", 1234), Student("Tinker_Bell", 1235) }; std::cerr << "----- Init list -----" << std::endl; std::list<Student> mylist; for(int i=0; i<2; i++) { mylist.push_back(students[i]); //mylist.insert(mylist.end(),students[i]); // equivalent with push_back //mylist.emplace_back(students[i].name, students[i].aem); //mylist.emplace(mylist.end(), students[i].name, students[i].aem); // equivalent with emplace_back } std::cerr << "-------------------------\n"; std::cerr << "mylist contains:"; for (std::list<Student>::iterator it = mylist.begin(); it!=mylist.end(); ++it) std::cerr << ' ' << *it; std::cerr << std::endl; std::cerr << "-------------------------\n"; return 0; }
Κατεβάστε, μεταγλωττίστε και εκτελέστε το παραπάνω πρόγραμμα. Ποιος κατασκευαστής καλείται κατά την κατασκευή των αντικείμενων μέσω της συνάρτησης push_back. Δοκιμάστε να αντικαταστήσετε τη push_back με την emplace_back και δοκιμάστε να μεταγλωττίσετε-εκτελέσετε ξανά. Παρατηρήστε τις διαφορές στις εκτυπώσεις στις δύο περιπτώσεις.
Κατά την εισαγωγή ενός στοιχείου μέσω των συναρτήσεων insert, insert_back, emplace, emplace_back δημιουργείται πάντα ένα νέο αντικείμενο στον container. Η δημιουργία του αντικείμένου γίνεται είτε μέσω του copy-constructor (μέθοδοι insert, insert_back) ή μέσω εκείνου του κατασκευαστή που λαμβάνει ως παραμέτρους τους τύπους των ορισμάτων που περνιούνται στις μεθόδους emplace ή emplace_back. Στο παράδειγμα μας, τα αντικείμενα κατασκευάζονται με τη βοήθεια του κατασκευαστή Student(const char *name, int aem).
Αντιστοίχως, στο παρακάτω πρόγραμμα ανατίθεται σε ένα container τύπου array περιεχόμενα μέσω του τελεστή []. Μεταγλωττίζοντας και εκτελώντας το πρόγραμμα θα παρατηρήσετε ότι καλείται ο τελεστής = (operator=) της κλάσης Student.
#include <iostream> // std::cout #include <algorithm> // std::copy #include <array> // std::array #include <array> // std::array #include "Student.hpp" int main () { Student students[] = { Student("Peter_Pan", 1234), Student("Tinker_Bell", 1235) }; std::cerr << "----- Init array -----" << std::endl; std::array<Student,2> myarray; for(int i=0; i<2; i++) { myarray[i] = students[i]; } std::cerr << "-------------------------\n"; std::cerr << "myarray contains:"; for (std::array<Student,2>::iterator it = myarray.begin(); it!=myarray.end(); ++it) std::cerr << ' ' << *it; std::cerr << std::endl; std::cerr << "-------------------------\n"; return 0; }
Όταν στην STL προσδιορίζεται ένα εύρος στοιχείων εντός ενός container μεταξύ των υποτιθέμενων θέσεων start και stop ( οι θέσεις αυτές προσδιορίζονται πάντοτε από iterators), το διάστημα το οποιό υπολογίζεται είναι από start (συμπεριλαμβανομένου) έως και stop (μη συμπεριλαμβανομένου), ισοδύναμα: [start, stop). Η παρακάτω εικόνα περιγράφει το διάστημα μεταξύ των θέσεων start=1 και stop=6 ενός πίνακα. Το προσδιορισθέν διάστημα είναι από start έως και stop-1, δηλαδή από 1 έως και 5 (με πράσινο χρώμα).
Δείτε το παρακάτω παράδειγμα, όπου αντιγράφονται τα περιεχόμενα του πίνακα array αρχικά στον πίνακα myarray και στη συνέχεια ένα μέρος από αυτά στη λιστα mylist.
#include <iostream> // std::cout #include <algorithm> // std::copy #include <list> // std::list #include <array> // std::array #include "Student.hpp" #define SIZE 10 int main () { int array[] = { 1,2,3,4,5,6,7,8,9,10 }; std::array<int,SIZE> myarray; for(int i=0; i<SIZE; i++) myarray[i] = array[i]; std::cerr << "myarray contains:"; for (std::array<int,SIZE>::iterator it = myarray.begin(); it!=myarray.end(); ++it) std::cerr << ' ' << *it; std::cerr << std::endl; // myarray: 1 2 3 4 5 6 7 8 9 std::list<int> mylist; mylist.assign(myarray.cbegin() + 1, myarray.cbegin() + 4); std::cerr << "mylist contains:"; for (std::list<int>::iterator it = mylist.begin(); it!=mylist.end(); ++it) std::cerr << ' ' << *it; std::cerr << std::endl; return 0; }
Η μέθοδος assign δημιουργεί ένα αντίγραφο των περιεχομένων ξεκινώντας από το πρώτο όρισμα (συμπεριλαμβανομένου) έως και το δεύτερο όρισμα (μη συμπεριλαμβανομένου). Στο παραπάνω παράδειγμα ξεκινά από τη θέση 1 του πίνακα (myarray.cbegin()+1) έως και τη θέση 3 (myarray.cbegin()+3). Η θέση myarray.cbegin()+4 που είναι το 2ο όρισμα δεν περιλαμβάνεται στο διάστημα.
Σε αναλογία μετα παραπάνω, όπως θα δούμε στη συνέχεια, οι iterators της STL διατρέχουν οποιαδήποτε δομή από τη θέση begin() (δείκτης στην πρώτη θέση περιεχομένων του container) έως end() (δείκτης αμέσως μετά την τελευταία θέση περιεχομένων του container).