| Both sides previous revisionPrevious revisionNext revision | Previous revision | 
| cpp:stl:iterators [2022/05/26 17:11]  –  gthanos | cpp:stl:iterators [2023/05/30 18:48] (current)  –  gthanos | 
|---|
| Οι κατηγορίες (τύποι)των //iterator// είναι οι παρακάτω. Ένας //iterator// μπορεί να ανήκει σε περισσότερους από ένα τύπους. | Οι κατηγορίες (τύποι)των //iterator// είναι οι παρακάτω. Ένας //iterator// μπορεί να ανήκει σε περισσότερους από ένα τύπους. | 
 |  | 
|   * **Input Iterator:** Πρόκειται για έναν //iterator// από τον οποίο μπορούμε να διαβάσουμε το τρέχον στοιχείο της δομής στο οποίο δείχνει. Πρόκειται για έναν //iterator// ανάγνωσης του περιεχόμενου της δομής. Όλοι οι διαθέσιμοι //iterators// είναι //Input Iterators//. Παράδειγμα:  |   * **Input Iterator:** Πρόκειται για έναν //iterator// από τον οποίο μπορούμε μόνο να διαβάσουμε το τρέχον στοιχείο της δομής στο οποίο δείχνει. Πρόκειται για έναν //iterator// ανάγνωσης του περιεχόμενου της δομής. Όλοι οι διαθέσιμοι //iterators// είναι //Input Iterators//. Παράδειγμα:  | 
| <code cpp> |   | 
|   | <code cpp input_iterator.cpp>  | 
|   | #include <vector>  | 
|   | #include <iostream>  | 
|   | #define SIZE 10  | 
|   | using namespace std;  | 
|   |    | 
|   | int main() {  | 
|   |   vector<int> ints;  | 
|   |   for(int i=0; i<10; i++)  | 
|   |     ints.push_back(SIZE-i);  | 
|   |   | 
|   for(vector<int>::const_iterator it=ints.cbegin(); it!=ints.cend(); it++) |   for(vector<int>::const_iterator it=ints.cbegin(); it!=ints.cend(); it++) | 
|     cout << *it << " "; |     cout << *it << " "; | 
|   cout << endl; |   cout << endl; | 
|   | } | 
| </code> | </code> | 
|   * **Output Iterator:** Πρόκειται για έναν //iterator// μέσω του οποίου μπορούμε να γράψουμε στο τρέχον στοιχείο του //container//. Οι //iterators// που στον τύπο τους περιέχουν το συνθετικό //const_// (const_iterator, const_reverse_iterator) δεν ανήκουν στη συγκεκριμένη κατηγορία. Παραδείγματα:  |   * **Output Iterator:** Πρόκειται για έναν //iterator// μέσω του οποίου μπορούμε να διαβάσουμε και να γράψουμε στο τρέχον στοιχείο του //container//. Οι //iterators// που στον τύπο τους περιέχουν το συνθετικό //const_// (const_iterator, const_reverse_iterator) δεν ανήκουν στη συγκεκριμένη κατηγορία. Παραδείγματα:  | 
| <code cpp> | <code cpp output_iterator.cpp>  | 
|   | #include <vector>  | 
|   | #include <iostream>  | 
|   | #define SIZE 10  | 
|   | using namespace std;  | 
|   |    | 
|   | int main() {  | 
|   |   vector<int> ints;  | 
|   |   for(int i=0; i<10; i++)  | 
|   |     ints.push_back(SIZE-i);  | 
|   |   | 
|   for(vector<int>::iterator it=ints.begin(); it!=ints.end(); it++) { |   for(vector<int>::iterator it=ints.begin(); it!=ints.end(); it++) { | 
|     *it += 10;                         // we modify container here |     *it += 10;                         // we modify container here | 
|     cout << *it << " "; |     cout << *it << " "; | 
|   } |   } | 
|   |   cout << endl; | 
|    |    | 
|   for(vector<int>::const_iterator it=ints.cbegin(); it!=ints.cend(); it++) { |   for(vector<int>::const_iterator it=ints.cbegin(); it!=ints.cend(); it++) { | 
|     cout << *it << " "; |     cout << *it << " "; | 
|   } |   } | 
|   | } | 
| </code> | </code> | 
|   * **Bidirectional Iterator:** Πρόκειται για iterators που εκτός των πράξεων ''++it'', ''it++'' υποστηρίζουν και τις πράξεις ''%%--%%it'', ''it%%--%%''. //Bidirectional Iterators// είναι όλοι οι //iterators// με εξαίρεση εκείνούς που ανήκουν σε //Unordered Associative Containers// και οι //iterators// του //container forward_list// (απλά συνδεδεμένη λίστα). Παραδείγματα: |   * **Bidirectional Iterator:** Πρόκειται για iterators που εκτός των πράξεων ''++it'', ''it++'' υποστηρίζουν και τις πράξεις ''%%--%%it'', ''it%%--%%''. //Bidirectional Iterators// είναι όλοι οι //iterators// με εξαίρεση εκείνούς που ανήκουν σε //Unordered Associative Containers// και οι //iterators// του //container forward_list// (απλά συνδεδεμένη λίστα). Παραδείγματα: | 
| <code cpp>  | <code cpp bidirectional_iterator.cpp>  | 
|   for(vector<int>::iterator it=ints.cbegin(); it!=ints.cend(); it++) {  | #include <iostream>  | 
|     cout << *it << " ";  | #include <vector>  | 
|   }  | #define SIZE 10  | 
|   cout << endl;  |   | 
|     | using namespace std;  | 
|   vector<int>::iterator it = ints.cend(); // starting from the end of the container |   | 
|   | int main() {  | 
|   |   vector<int> ints(SIZE);  | 
|   |   for(int i=0; i<SIZE; i++)  | 
|   |     ints[i] = i+1;  | 
|   |    | 
|   |   vector<int>::const_iterator it = ints.cend(); // starting from the end of the container | 
|   while(true) { |   while(true) { | 
|     --it1;                                // move to the previous element  |     --it;                                // move to the previous element  | 
|     cout << *it1 << " ";  |     cout << *it << " ";  | 
|     if(it1 == ints.cbegin())              // stop when we reach the first element |     if(it == ints.cbegin())              // stop when we reach the first element | 
|       break; |       break; | 
|   } |   } | 
|   cout << endl; |   cout << endl; | 
|   | } | 
| </code> | </code> | 
 |  | 
| #include <iostream> | #include <iostream> | 
| #include <vector> | #include <vector> | 
|   | #define SIZE 10 | 
 |  | 
| int main ()  | int main () {  | 
| {  |   std::vector<int> myvector (SIZE);  // SIZE default-constructed ints | 
|   std::vector<int> myvector (5);  // 5 default-constructed ints  |  | 
|   int i=0; |   int i=0; | 
|   |     | 
|   std::vector<int>::reverse_iterator rit = myvector.rbegin();  |   for (std::vector<int>::reverse_iterator rit = myvector.rbegin(); rit!= myvector.rend(); ++rit) | 
|   for (; rit!= myvector.rend(); ++rit) |  | 
|     *rit = ++i; |     *rit = ++i; | 
 |  | 
| </code> | </code> | 
|   * **Random Access Iterators:** Πρόκειται για //iterators// που υποστηρίζουν την πράξη της πρόσθεσης και τις αφαίρεσης μεταξύ του //iterator// και ενός ακεραίου αριθμού (η πράξη είναι ανάλογη της αριθμητικής δεικτών). Οι //iterators// αυτής της κατηγορίας υποστηρίζονται από τους //Sequence Containers// //array//, //vector// και //deque// αλλά όχι από τους //containers list// και //forward_list//. Παράδειγμα: |   * **Random Access Iterators:** Πρόκειται για //iterators// που υποστηρίζουν την πράξη της πρόσθεσης και τις αφαίρεσης μεταξύ του //iterator// και ενός ακεραίου αριθμού (η πράξη είναι ανάλογη της αριθμητικής δεικτών). Οι //iterators// αυτής της κατηγορίας υποστηρίζονται από τους //Sequence Containers// //array//, //vector// και //deque// αλλά όχι από τους //containers list// και //forward_list//. Παράδειγμα: | 
| <code cpp> | <code cpp random_access_iterator.cpp>  | 
|   | #include <iostream>  | 
|   | #include <vector>  | 
|   | #define SIZE 10  | 
|   |   | 
|   | using namespace std;  | 
|   |   | 
|   | int main() {  | 
|   |   vector<int> ints(SIZE);  | 
|   |   for(int i=0; i<SIZE; i++)  | 
|   |     ints[i] = i+1; | 
|    |    | 
|   vector<int>::iterator it = ints.cend(); // starting from the end of the container  |   vector<int>::const_iterator it = ints.cend(); // starting past the end of the container  | 
|   while(true) { |   while(it > ints.cbegin()) { | 
|     it -= 2;                              // move back by 2 elements |     it -= 2;                              // move back by 2 elements | 
|     cout << *it1 << " ";  |     cout << *it << " ";  | 
|     if(it1 <= ints.cbegin())              // stop when we reach or we have passed the first element |     if(it <= ints.cbegin())              // stop when we reach or we have passed the first element | 
|       break; |       break; | 
|   } |   } | 
|   cout << endl; |   cout << endl; | 
|   | } | 
| </code> | </code> | 
 |  | 
| Εάν θέλουμε να υπολογίσουμε την απόσταση μεταξύ δύο //iterators// παρέχεται η συνάρτηση [[http://www.cplusplus.com/reference/iterator/distance/|distance]] η οποία υπολογίζει την απόσταση από το πρώτο όρισμα (//first//) έως το δεύτερο όρισμα (//last//) μετακινώντας τον δείκτη από //first// έως //last// με χρήση του τελεστή ''++''. Η συνάρτηση υποθέτει ότι το //first// βρίσκεται πριν από το //last//. | Εάν θέλουμε να υπολογίσουμε την απόσταση μεταξύ δύο //iterators// παρέχεται η συνάρτηση [[http://www.cplusplus.com/reference/iterator/distance/|distance]] η οποία υπολογίζει την απόσταση από το πρώτο όρισμα (//first//) έως το δεύτερο όρισμα (//last//) μετακινώντας τον δείκτη από //first// έως //last// με χρήση του τελεστή ''++''. Η συνάρτηση υποθέτει ότι το //first// βρίσκεται πριν από το //last//. | 
 |  | 
| ===== Κοινές συναρτήσεις για όλους τους containers για την επιστροφή των θέσεων αρχής και τέλους ===== | Δείτε το παρακάτω παράδειγμα χρήσης των συγκεκριμένων συναρτήσεων   | 
|   |   | 
|   | <code cpp advance_distance.cpp>  | 
|   | #include <iostream>     // std::cout  | 
|   | #include <iterator>     // std::advance  | 
|   | #include <list>         // std::list  | 
|   |   | 
|   | int main () {  | 
|   |   std::list<int> mylist;  | 
|   |   for (int i=0; i<10; i++) mylist.push_back (i*10);  | 
|   |     | 
|   |   for(std::list<int>::const_iterator it = mylist.cbegin(); it!=mylist.cend(); ++it)  | 
|   |     std::cout << *it << " ";  | 
|   |   std::cout << std::endl;  | 
|   |   | 
|   |   std::list<int>::iterator it = mylist.begin();  | 
|   |     | 
|   |   std::advance (it,5);  | 
|   |   | 
|   |   std::cout << "The sixth element in mylist is: " << *it << '\n';  | 
|   |     | 
|   |   std::list<int>::iterator it1 = mylist.begin();  | 
|   |   std::advance(it1,2);  | 
|   |     | 
|   |   std::list<int>::iterator it2 = mylist.end();  | 
|   |   std::advance(it2,-2);  | 
|   |     | 
|   |   std::cout << "Distance between it1 and it2 is: " << distance(it1, it2) << std::endl;  | 
|   |   | 
|   |   return 0;  | 
|   | }  | 
|   | </code>  | 
|   |   | 
|   | ==== Κοινές συναρτήσεις για όλους τους containers για την επιστροφή των θέσεων αρχής και τέλους ==== | 
 |  | 
| H //STL// παρέχει τις //templated// συναρτήσεις [[http://www.cplusplus.com/reference/iterator/begin/|begin]] και [[http://www.cplusplus.com/reference/iterator/end|end]] για την εύρεση της αρχικής και της τελικής θέσης οποιουδήποτε //container//. Οι συναρτήσεις αυτές είναι διαφορετικές από τις συναρτήσεις μέλη //begin// και //end// που περιέχει κάθε //container//. Παράδειγμα χρήσης των συναρτήσεων αυτών δίνεται παρακάτω: | H //STL// παρέχει τις //templated// συναρτήσεις [[http://www.cplusplus.com/reference/iterator/begin/|begin]] και [[http://www.cplusplus.com/reference/iterator/end|end]] για την εύρεση της αρχικής και της τελικής θέσης οποιουδήποτε //container//. Οι συναρτήσεις αυτές είναι διαφορετικές από τις συναρτήσεις μέλη //begin// και //end// που περιέχει κάθε //container//. Παράδειγμα χρήσης των συναρτήσεων αυτών δίνεται παρακάτω: |