I valori chiave degli elementi in a std::setsono constper una buona ragione. La loro modifica può distruggere l'ordine che è essenziale per a std::set.
Quindi, la soluzione è cancellare l'iteratore e inserirne uno nuovo con chiave *it - sub. Tieni presente che std::set::erase()restituisce un nuovo iteratore che deve essere utilizzato nel tuo caso per far funzionare correttamente il ciclo while.
#include<iostream>
#include<set>
template <typename T>
std::ostream& operator<<(std::ostream &out, const std::set<T> &values)
{
const char *sep = "{ ";
for (const T &value : values) { out << sep << value; sep = ", "; }
return out << " }";
}
int main()
{
std::set<int> test{ 11, 12, 13, 14, 15 };
std::cout << "test: " << test << '\n';
const int sub = 10;
std::set<int>::iterator iter = test.begin();
while (iter != test.end()) {
const int value = *iter;
iter = test.erase(iter);
test.insert(value - sub);
}
std::cout << "test: " << test << '\n';
}
Produzione:
test: { 11, 12, 13, 14, 15 }
test: { 1, 2, 3, 4, 5 }
Demo live su coliru
I cambiamenti durante l' std::setiterazione su di esso non sono un problema in generale, ma possono causare problemi sottili.
Il fatto più importante è che tutti gli iteratori utilizzati devono essere mantenuti intatti o non possono più essere utilizzati. (Ecco perché l'attuale iteratore dell'elemento di cancellazione viene assegnato con il valore di ritorno di std::set::erase()cui è un iteratore intatto o la fine dell'insieme.)
Naturalmente, è possibile inserire elementi anche dietro l'attuale iteratore. Anche se questo non è un problema in merito std::set, potrebbe interrompere il ciclo del mio esempio precedente.
Per dimostrarlo, ho modificato un po 'l'esempio sopra. Si prega di notare che ho aggiunto un contatore aggiuntivo per garantire la chiusura del loop:
#include<iostream>
#include<set>
template <typename T>
std::ostream& operator<<(std::ostream &out, const std::set<T> &values)
{
const char *sep = "{ ";
for (const T &value : values) { out << sep << value; sep = ", "; }
return out << " }";
}
int main()
{
std::set<int> test{ 11, 12, 13, 14, 15 };
std::cout << "test: " << test << '\n';
const int add = 10;
std::set<int>::iterator iter = test.begin();
int n = 7;
while (iter != test.end()) {
if (n-- > 0) {
const int value = *iter;
iter = test.erase(iter);
test.insert(value + add);
} else ++iter;
}
std::cout << "test: " << test << '\n';
}
Produzione:
test: { 11, 12, 13, 14, 15 }
test: { 23, 24, 25, 31, 32 }
Demo live su coliru