Les valeurs clés des éléments dans a std::setsont constpour une bonne raison. Les modifier peut détruire l'ordre qui est essentiel pour a std::set.
Par conséquent, la solution consiste à effacer l'itérateur et à en insérer un nouveau avec la clé *it - sub. Veuillez noter que std::set::erase()renvoie un nouvel itérateur qui doit être utilisé dans votre cas pour que la boucle while fonctionne correctement.
#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';
}
Production:
test: { 11, 12, 13, 14, 15 }
test: { 1, 2, 3, 4, 5 }
Démo en direct sur coliru
Les changements en cours d' std::setitération ne sont pas un problème en général mais peuvent provoquer des problèmes subtils.
Le fait le plus important est que tous les itérateurs utilisés doivent être conservés intacts ou ne plus être utilisés. (C'est pourquoi l'itérateur actuel de l'élément d'effacement est affecté avec la valeur de retour std::set::erase()qui est soit un itérateur intact ou la fin de l'ensemble.)
Bien sûr, des éléments peuvent également être insérés derrière l'itérateur actuel. Bien que ce ne soit pas un problème concernant le, std::setcela peut casser la boucle de mon exemple ci-dessus.
Pour le démontrer, j'ai un peu modifié l'exemple ci-dessus. Veuillez noter que j'ai ajouté un compteur supplémentaire pour accorder la fin de la boucle:
#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';
}
Production:
test: { 11, 12, 13, 14, 15 }
test: { 23, 24, 25, 31, 32 }
Démo en direct sur coliru