Ce face std::vector::insert
insert pune elemente noi înaintea iteratorului poz. Toate elementele de la poz încolo se mută cu o poziție (sau cu n poziții) spre dreapta, deci inserarea la început sau la mijloc durează proporțional cu numărul de elemente mutate. insert(v.end(), x) este echivalent cu push_back(x).
emplace(poz, argumente...) face același lucru pentru un singur element, dar îl construiește direct din argumentele constructorului, ca emplace_back.
Invalidare: dacă inserarea realocă memoria (nu mai este loc), toți iteratorii și referințele devin invalide. Dacă nu realocă, devin invalide cele de la poz încolo. De aceea, insert returnează un iterator nou, valid, la primul element inserat: folosește-l pe acela.
Parametri
| Parametru | Descriere |
|---|---|
poz |
Iterator: elementele noi se pun înaintea lui. begin() = la început, end() = la final. |
valoare / n |
Valoarea de inserat și, opțional, de câte ori. |
prim, ultim |
Un interval din alt container, copiat în vector. |
lista |
O listă între acolade: {1, 2, 3}. |
Ce returnează
Un iterator la primul element inserat (sau poz, dacă nu s-a inserat nimic).
Exemple
Exemplul 1: Inserare la început, la mijloc și din alt vector
#include <print>
#include <string>
#include <vector>
int main() {
std::vector<std::string> traseu{"București", "Brașov", "Cluj"};
traseu.insert(traseu.begin() + 1, "Ploiești"); // înainte de Brașov
traseu.insert(traseu.begin(), "Constanța"); // la început
std::println("{}", traseu);
std::vector<std::string> extra{"Oradea", "Arad"};
traseu.insert(traseu.end(), extra.begin(), extra.end()); // la final
std::println("{}", traseu);
std::vector<int> v{1, 5};
v.insert(v.begin() + 1, {2, 3, 4});
v.insert(v.end(), 3, 0); // trei zerouri
std::println("{}", v);
}
Rezultat
["Constanța", "București", "Ploiești", "Brașov", "Cluj"]
["Constanța", "București", "Ploiești", "Brașov", "Cluj", "Oradea", "Arad"]
[1, 2, 3, 4, 5, 0, 0, 0]
Exemplul 2: Folosește iteratorul returnat
După fiecare inserare iteratorul vechi poate fi invalid. Reținem cel returnat de insert și sărim peste elementul nou cu ++it.
#include <print>
#include <vector>
int main() {
std::vector<int> v{1, 2, 3, 4};
// Inserăm un 0 înaintea fiecărui număr par.
for (auto it = v.begin(); it != v.end(); ++it) {
if (*it % 2 == 0) {
it = v.insert(it, 0); // it indică acum 0-ul nou
++it; // înapoi la numărul par
}
}
std::println("{}", v);
}
Rezultat
[1, 0, 2, 3, 0, 4]
Exemplul 3: emplace la o poziție
#include <print>
#include <string>
#include <utility>
#include <vector>
int main() {
std::vector<std::pair<std::string, int>> clasament{{"Ana", 95}, {"Ion", 80}};
clasament.emplace(clasament.begin() + 1, "Elena", 88); // pair construit pe loc
for (const auto& [nume, puncte] : clasament) {
std::println("{}: {}", nume, puncte);
}
}
Rezultat
Ana: 95
Elena: 88
Ion: 80
Greșeli frecvente
- Continui să folosești iteratorul vechi după
insert:v.insert(it, x); ++it;. Dacă s-a realocat memoria,iteste invalid (comportament nedefinit). Scrieit = v.insert(it, x);. - Inserezi des la începutul unui vector mare. Fiecare inserare mută tot vectorul. Dacă adaugi des în față, folosește
std::deque, sau adaugă la final și inversează la sfârșit. - Inserezi elementele vectorului în el însuși cu un interval (
v.insert(v.begin(), v.begin(), v.end())). Iteratorii sursei nu au voie să provină din același vector: comportament nedefinit.
Comenzi înrudite
std::vector::erase: Șterge un element sau un interval de elemente din vector și returnează iteratorul elementului de după.std::vector::push_back: Adaugă un element la sfârșitul vectorului; vectorul crește cu o poziție.std::vector::emplace_back: Construiește un element nou direct la sfârșitul vectorului, din argumentele constructorului.std::deque: Coadă cu două capete: adăugare și ștergere rapidă atât la început, cât și la sfârșit, plus acces după poziție.