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 ως εξής:
#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.
Αντιστοίχως, στο παρακάτω πρόγραμμα ανατίθεται σε ένα 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 (μη συμπεριλαμβανομένου). Δείτε το παρακάτω παράδειγμα, όπου αντιγράφονται τα περιεχόμενα του πίνακα 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; std::list<int> mylist; mylist.assign(myarray.cbegin(), myarray.cbegin() + 3); 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 δημιουργεί ένα αντίγραφο των περιεχομένων ξεκινώντας από το πρώτο όρισμα (συμπεριλαμβανομένου) έως και το δεύτερο όρισμα (μη συμπεριλαμβανομένου). Στο παραπάνω παράδειγμα ξεκινά από τη θέση 0 του πίνακα (myarray.cbegin()) έως και τη θέση 2 (myarray.cbegin()+2). Η θέση myarray.cbegin()+3 που είναι το 2ο όρισμα δεν περιλαμβάνεται στο διάστημα.
Όπως θα δούμε και στη συνέχεια, οι iterators της STL διατρέχουν οποιαδήποτε δομή από τη θέση begin() (δείκτης στην πρώτη θέση περιεχομένων του container) έως end() (δείκτης αμέσως μετά την τελευταία θέση περιεχομένων του container).
Με εξαίρεση την κλάση std::array που το μέγεθος των πινάκων που δημιουργεί είναι σταθερό οι υπόλοιποι containers μπορούν να μεταβάλλουν το αριθμό των στοιχείων που αποθηκεύουν. Για την εισαγωγή ενός στοιχείου σε έναν container υπάρχει η συνάρτηση μέλους insert. Για sequence containers η insert λαμβάνει ως πρώτο όρισμα έναν iterator που δηλώνει τη θέση εισαγωγής