I'm using C++20.
I have an object MyObject that contains a variable std::set<std::set<int>> nestedSet. I need to iterate through nestedSet and remove from the second-level sets an element that matches a search criteria. So far, I've tried the implementations:
void MyObject::removeFromNestedSet(int criteria) {
for(auto s : nestedSet){
std::erase_if(s, [&criteria](int i){return i == criteria;});
}
}
and
void MyObject::removeFromNestedSet(int criteria) {
for(auto s : nestedSet){
auto it = s.find(criteria);
if(it != s.end()){
s.erase(it, s.end());
}
}
}
Viewing the code progression with a debugger, I can see that within the frame of the removeFromNestedSet function, the element in the set matching the criteria IS removed. However, this removal is not reflected when observing the this->nestedSet object.
I haven't worked with C++ in a few years, but I suspect this is an issue with needing the range-based loop to point to the actual nested sets within nestedSet rather than a copy of the nested set?
You are having difficulty because a std::set's elements are always const.
This is because a std::set's elements are always ordered by their values. Changing a value could violate the order.
You must remove each element from your outer std::set before you can modify it.
void MyObject::removeFromNestedSet(int criteria) {
std::set<std::set<int>> newNestedSet;
while ( ! nestedSet.empty() ) {
// Remove an inner set, so it can be modified
auto setNode = nestedSet.extract( nestedSet.begin() );
// Modify the set
std::erase_if(setNode.value(), [&](int i){return i == criteria;});
// Place the result in a new set
newNestedSet.insert(std::move(setNode));
}
nestedSet = std::move(newNestedSet);
}
This solution doesn't make any copies of your data and preserves the integrity of any pointers or references to your stored ints.
Note that your sets may be in a different order after your modification.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With