std::vector::emplace back (tsz. std::vector::emplace backs)
std::vector
-ba és az elemek hozzáadásábaA C++ Standard Template Library (STL) egyik leggyakrabban használt konténer típusa a std::vector
, amely dinamikusan méretezhető tömbként működik. A std::vector
lehetővé teszi, hogy dinamikusan növeljük vagy csökkentsük az elemek számát, miközben az elemek tárolása folyamatos memóriaterületen történik.
Az elemek hozzáadására több lehetőség is van:
push_back(const T& val)
— beszúr egy másolatot az elemről a vektor végére.push_back(T&& val)
— mozgató (move) verzió, amely átveszi az objektum tulajdonjogát.emplace_back(Args&&... args)
— új elemet hoz létre közvetlenül a helyén, a megadott paraméterek alapján.Ez a három közül az emplace_back
az egyik leghatékonyabb és legflexibilisebb módja az elemek hozzáadásának, különösen komplex osztályok esetén.
emplace_back
és hogyan működik?A std::vector::emplace_back
C++11-ben került bevezetésre, és egy olyan függvény, amely közvetlenül az adott paraméterekkel létrehozza az új elemet a vektor végén, anélkül, hogy egy külön objektumot először létrehoznánk, majd másolnánk vagy mozdítanánk be.
template <class... Args>
void emplace_back(Args&&... args);
emplace_back
egy paramétercsomagot (Args&&...
) vár, ami lehetővé teszi bármilyen számú és típusú argumentum továbbítását.
push_back
: Nem kell először egy ideiglenes objektumot létrehozni, majd azt beszúrni.
emplace_back
használatáraVegyünk egy egyszerű osztályt:
class Szemely {
public:
std::string nev;
int kor;
Szemely(const std::string& n, int k) : nev(n), kor(k) {
std::cout << "Szemely konstruktor: " << nev << ", " << kor << std::endl;
}
};
push_back
használatával:std::vector<Szemely> emberek;
Szemely s("Dani", 30);
emberek.push_back(s);
Ebben az esetben először létrejön az ideiglenes s
objektum, majd másolás vagy mozgatás történik a vektorba.
emplace_back
használatával:std::vector<Szemely> emberek;
emberek.emplace_back("Dani", 30);
Itt közvetlenül a "Dani"
és 30
argumentumokkal hívjuk meg a Szemely
konstruktorát, az objektum a vektor memóriájában jön létre, nem kell külön példányt előállítani.
emplace_back
általában a vektor aktuális kapacitását ellenőrzi.emplace_back
-tól vagy push_back
-tól, viszont az emplace_back
segítségével elkerülhető az ideiglenes objektum létrehozásának költsége.emplace_back
tökéletes továbbítást (perfect forwarding) alkalmaz a paramétereken, így az argumentumokat optimálisan továbbítja a konstruktorhoz.
emplace_back
-et?
emplace_back
és push_back
közöttTulajdonság | push_back
|
emplace_back
|
---|---|---|
Paraméter típusa | Objektumot vagy rvalue referencia | Konstruktor paramétereket vár |
Objektum létrehozás | Először objektum, majd másolás/mozgatás | Objektum közvetlenül a helyén jön létre |
Hatékonyság | Lehet több felesleges másolás | Hatékonyabb, kevesebb felesleges művelet |
Tökéletes továbbítás | Nem alkalmazza | Igen, tökéletes továbbítást használ |
Kompatibilitás | Minden C++ verzióban elérhető | Csak C++11-től kezdve |
struct Pont {
int x, y, z;
Pont(int _x, int _y, int _z) : x(_x), y(_y), z(_z) {}
};
std::vector<Pont> pontok;
pontok.emplace_back(10, 20, 30);
class Auto {
public:
std::string marka;
int evjarat;
Auto(const std::string& m, int ev) : marka(m), evjarat(ev) {}
};
std::vector<Auto> autok;
autok.emplace_back("Toyota", 2020);
class Ertek {
int x;
public:
Ertek(int v) : x(v) {}
};
std::vector<Ertek> vektor;
vulkan.emplace_back(5); // push_back nem működne így alapértelmezett konstruktor nélkül
emplace_back
használatakoremplace_back
csak C++11-től elérhető.
std::vector::emplace_back
egy rugalmas, hatékony módszer új elemek létrehozására és hozzáadására egy vektor végéhez.
#include <iostream>
#include <vector>
#include <string>
class Szemely {
public:
std::string nev;
int kor;
Szemely(const std::string& n, int k) : nev(n), kor(k) {
std::cout << "Szemely konstruktor: " << nev << ", " << kor << std::endl;
}
};
int main() {
std::vector<Szemely> emberek;
// push_back példány készítés után
Szemely s("Anna", 28);
emberek.push_back(s);
// emplace_back paraméterek közvetlen átadásával
emberek.emplace_back("Béla", 35);
std::cout << "Az emberek száma: " << emberek.size() << std::endl;
for (const auto& e : emberek) {
std::cout << e.nev << " (" << e.kor << " éves)" << std::endl;
}
return 0;
}