User Tools

Site Tools


cpp:stl:insert_vs_emplace

Εισαγωγή στοιχείων μέσω των συναρτήσεων insert και emplace

Οι μέθοδοι insert και emplace εισάγουν στοιχεία σε ένα container, αλλά το κάνουν με διαφορετικό τρόπο. Η μέθοδος insert λαμβάνει ως παράμετρο το προς εισαγωγή αντικείμενο και με την βοήθεια του copy-constructor του αντικείμένου αντιγράφει το αντικείμενο μέσα στην δομή. Η μέθοδος συνεπάγεται α) την δημιουργία του αντικειμένου, β) την αντιγραφή του κατά την κλήση της insert και την αντιγραφή του στον container.

Αντίθετα, η μέθοδος emplace λαμβάνει μεταβλητό αριθμό παραμέτρων και αποσκοπεί στην δημιουργία του προς ένθεση αντικειμένου μία φορά εντός του container, καλώντας τον κατάλληλο κατασκευαστή για το αντικείμενο. Η επιλογή του κατασκευαστή γίνεται με βάση τον αριθμό και των τύπο των ορισμάτων που λαμβάνει η συνάρτηση emplace.

Για παράδειγμα, για την ένθεση στοιχείων της κλάσης Student μέσα σε ένα container list τα στοιχεία θα αντιγραφούν εντός του list στο τέλος της λίστας (όλες οι μέθοδοι insert ή emplace στον παρακάτω κώδικα - είτε βρίσκονται σε σχόλια, είτε όχι - εισάγουν το αντικείμενο στο τέλος της λίστας):

student_list.cpp
#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), Student("Mickey Mouse", 1236), Student("Minnie Mouse", 1237) };
 
  std::cerr << "----- Init list -----" << std::endl;
  std::list<Student> 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<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 και δοκιμάστε να μεταγλωττίσετε-εκτελέσετε ξανά. Τοποθετήστε κατάλληλα 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).
cpp/stl/insert_vs_emplace.txt · Last modified: 2023/05/29 17:20 by gthanos