Reputation: 586
Given std::set
, what is the best way to change the set during time-iteration?
For example:
std::set<T> s; // T is a some type (it's not important for the question).
// insertions to s
for (std::set<T>::iterator it = s.begin(); it != s.end(); it++) {
T saveIt(*it);
s.erase(*it);
s.insert( saveIt + saveIt ); // operator+ that defined at `T`
}
According to what that I read in some sources, it's bad way because that: the removing from the set may change the structure of the set.
So what is the better (/best) way to do it?
Upvotes: 1
Views: 98
Reputation: 19790
Just have a copy std:set
std::set<T> s;
std::set<T> modified_s;
for (std::set<T>::iterator it = s.begin(); it != s.end(); it++) {
modified_s.insert(*it+ *it);
}
s = std::move(modified_s);
Edit:
Added std::move
as improvement from @Jodocus
Upvotes: 0
Reputation: 136228
Your loop may result in almost endless loop because you keep adding larger elements at the back of your set. Until T + T
overflows.
Correct way is to create a new set:
std::set<T> s;
std::set<T> s2;
for(auto const& elem : s)
s2.insert(elem + elem);
s.swap(s2);
With boost::range
it is a one-liner:
#include <boost/range/adaptor/transformed.hpp>
// ...
std::set<int> s;
s = boost::copy_range<std::set<int>>(s | boost::adaptors::transformed([](int x) { return x + x; }));
Upvotes: 7