====== Εισαγωγή στοιχείων μέσω των συναρτήσεων insert και emplace ====== Οι μέθοδοι //insert// και //emplace// εισάγουν στοιχεία σε ένα //container//, αλλά το κάνουν με διαφορετικό τρόπο. Η μέθοδος //insert// λαμβάνει ως παράμετρο το προς εισαγωγή αντικείμενο και με την βοήθεια του copy-constructor του αντικείμένου αντιγράφει το αντικείμενο μέσα στην δομή. Η μέθοδος συνεπάγεται α) την δημιουργία του αντικειμένου, β) την αντιγραφή του κατά την κλήση της insert και την αντιγραφή του στον container. Αντίθετα, η μέθοδος //emplace// λαμβάνει μεταβλητό αριθμό παραμέτρων και αποσκοπεί στην δημιουργία του προς ένθεση αντικειμένου μία φορά εντός του //container//, καλώντας τον κατάλληλο κατασκευαστή για το αντικείμενο. Η επιλογή του κατασκευαστή γίνεται με βάση τον αριθμό και των τύπο των ορισμάτων που λαμβάνει η συνάρτηση //emplace//. Για παράδειγμα, για την ένθεση στοιχείων της κλάσης [[https://courses.e-ce.uth.gr/ECE326/doku.php?do=export_code&id=cpp:templates&codeblock=0|Student]] μέσα σε ένα //container list// τα στοιχεία θα αντιγραφούν εντός του //list// στο τέλος της λίστας (όλες οι μέθοδοι //insert// ή //emplace// στον παρακάτω κώδικα - είτε βρίσκονται σε σχόλια, είτε όχι - εισάγουν το αντικείμενο στο τέλος της λίστας): #include // std::cout #include // std::copy #include // std::list #include // std::array #include "Student.hpp" int main () { Student students[] = { Student("Peter_Pan", 1234), Student("Tinker_Bell", 1235), Student("Mickey Mouse", 1236), Student("Minnie Mouse", 1237) }; std::cerr << "----- Init list -----" << std::endl; std::list mylist; for(int i=0; i<4; i++) { mylist.insert(mylist.end(),students[i]); // equivalent with push_back //mylist.emplace(mylist.end(), students[i].getName(), students[i].getAEM()); // equivalent with emplace_back } std::cerr << "-------------------------\n"; std::cerr << "mylist contains:"; for (std::list::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// και δοκιμάστε να μεταγλωττίσετε-εκτελέσετε ξανά. Τοποθετήστε κατάλληλα //debug// μηνύματα στους κατασκευαστές της κλάσης //Student// και παρατηρήστε τις διαφορές στις εκτυπώσεις στις δύο περιπτώσεις. Κατά την εισαγωγή ενός στοιχείου μέσω των συναρτήσεων //insert//, //insert_back//, //insert_front// //emplace//, //emplace_back//, //emplace_front// δημιουργείται πάντα ένα νέο αντικείμενο στον //container// που αποτελεί αντίγραφο του προς εισαγωγή αντικειμένου. Η δημιουργία του αντικειμένου γίνεται είτε * μέσω του copy-constructor, όταν καλούνται οι μέθοδοι //insert//, //insert_front// και //insert_back// ή * μέσω εκείνου του κατασκευαστή που λαμβάνει ως παραμέτρους τους τύπους των ορισμάτων που περνιούνται στις μεθόδους //emplace// ή //emplace_front// ή //emplace_back//. Οι μέθοδοι //emplace// δημιουργούν ένα αντικείμενο χρησιμοποιώντας τον κατασκευαστή της κλάσης αντί για τη χρήση του //copy-constructor//. Το δυνητικό πλεονέκτημα των μεθόδων αυτών είναι ότι δεν κατασκευάζεται ένα αντικείμενο που στη συνέχεια αντιγράφεται, αλλά δημιουργείται μόνο ένα αντικείμενο εξ' αρχής. Στο προηγούμενο παράδειγμα, τα αντικείμενα κατασκευάζονται με τη βοήθεια του κατασκευαστή ''Student(const char *name, int aem)''.